From c878c4b1a9175154c9a3bef4e1d91fd7a23c4acc Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 16:51:48 -0400 Subject: [PATCH 01/73] Share TypeScript API projection Extract every TypeScript-specific resolution decision out of AtsTypeScriptCodeGenerator into TypeScriptApiProjector: type mapping, options flattening, callback shaping, promise wrapping, and fluent return selection. The generator consumes the resolved model instead of recomputing those decisions inline, and TypeScriptApiExportWriter serializes the same model into a schema version 1 canonical export. Documentation that reconstructs signatures from raw ATS drifts from the SDK that actually ships (microsoft/aspire#17608). Sharing one projection makes that drift impossible: the generated aspire.mts snapshots are byte-identical, and a new test asserts every exported declaration appears verbatim in the corresponding generated public interface. Ownership is resolved per capability rather than per type, mirroring AtsContextFilter, so a package that extends another package's resource documents its own members without republishing the referenced type. Referenced types contribute opaque declaration fragments keyed by their real owner, which lets a manifest concatenate packages and type-check without site-authored shims. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../AtsTypeScriptCodeGenerator.cs | 1894 +---- .../TypeScriptApiExportWriter.cs | 188 + .../TypeScriptApiModel.cs | 257 + .../TypeScriptApiProjector.cs | 2329 ++++++ .../Aspire.Hosting.RemoteHost.csproj | 4 + .../AtsTypeScriptCodeGeneratorTests.cs | 215 +- ...eneratorTests.ApiDeclarations.verified.txt | 951 +++ ...CodeGeneratorTests.ApiExport.verified.json | 6934 +++++++++++++++++ 8 files changed, 11127 insertions(+), 1645 deletions(-) create mode 100644 src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs create mode 100644 src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs create mode 100644 src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs create mode 100644 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt create mode 100644 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index 3d3f855f1cb..ec072681832 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -4,7 +4,6 @@ using System.Globalization; using System.Text; using System.Text.Json.Nodes; -using Aspire.Shared.CodeGeneration; using Aspire.Shared.Json; using Aspire.TypeSystem; @@ -110,355 +109,12 @@ internal sealed class AtsTypeScriptCodeGenerator : ICodeGenerator { private TextWriter _writer = null!; - // Mapping of typeId -> wrapper class name for all generated wrapper types - // Used to resolve parameter types to wrapper classes instead of handle types - private readonly Dictionary _wrapperClassNames = new(StringComparer.Ordinal); - private readonly Dictionary _typeRefsById = new(StringComparer.Ordinal); - - // Set of type IDs that have Promise wrappers (types with chainable methods) - // Used to determine return types for methods - private readonly HashSet _typesWithPromiseWrappers = new(StringComparer.Ordinal); - - // Set of generated options interfaces to avoid duplicates - private readonly HashSet _generatedOptionsInterfaces = new(StringComparer.Ordinal); - - // Collected options interfaces to generate (interface name -> list of optional params) - private readonly Dictionary> _optionsInterfacesToGenerate = new(StringComparer.Ordinal); - - // Mapping from CapabilityId to the options interface name it should use. - // When methods share a name but have incompatible callback parameter types, - // separate options interfaces are generated with numeric suffixes. - private readonly Dictionary _capabilityOptionsInterfaceMap = new(StringComparer.Ordinal); - - // Mapping of enum type IDs to TypeScript enum names - private readonly Dictionary _enumTypeNames = new(StringComparer.Ordinal); - - // Mapping of handle type IDs to XML documentation captured during ATS scanning. - private readonly Dictionary _handleDocumentationById = new(StringComparer.Ordinal); - - // Mapping of DTO type IDs to DTO metadata for generated argument marshalling. - private readonly Dictionary _dtoTypesById = new(StringComparer.Ordinal); - - private static string GetInterfaceName(string className) => className; - - private static string GetPromiseInterfaceName(string className) => $"{className}Promise"; - - private static string GetImplementationClassName(string className) => $"{className}Impl"; - - private static string GetImplementationPromiseClassName(string className) => $"{className}PromiseImpl"; - - private static string GetReferenceExpressionInterfaceName() => "ReferenceExpression"; - - private static string GetCancellationTokenInterfaceName() => "CancellationToken"; - - private static string GetHandleReferenceInterfaceName() => "HandleReference"; - - private static string GetInputTypeEnumName() => "InputType"; - - private static string GetInteractionInputInterfaceName() => "InteractionInput"; - - private static string GetInteractionInputCollectionClassName() => "InteractionInputCollection"; - - private const string InputTypeTypeId = "enum:Aspire.Hosting.InputType"; - - private const string InteractionInputTypeId = "Aspire.Hosting/Aspire.Hosting.InteractionInput"; - - private const string InteractionInputCollectionTypeId = "Aspire.Hosting/Aspire.Hosting.InteractionInputCollection"; - - private string GetConcreteClassName(string typeId) => _wrapperClassNames.GetValueOrDefault(typeId) - ?? DeriveClassName(typeId); - - private string GetPublicPromiseInterfaceName(string typeId) => GetPromiseInterfaceName(GetConcreteClassName(typeId)); - - private static bool IsHandleType(AtsTypeRef? typeRef) => - typeRef is { Category: AtsTypeCategory.Handle }; - - /// - /// Maps an AtsTypeRef to a TypeScript type using category-based dispatch. - /// This is the preferred method - uses type metadata rather than string parsing. - /// - private string MapTypeRefToTypeScript(AtsTypeRef? typeRef) - { - if (typeRef is null) - { - return "unknown"; - } - - // ReferenceExpression is a value type defined in base.mts, not a handle-based wrapper - if (typeRef.TypeId == AtsConstants.ReferenceExpressionTypeId) - { - return GetReferenceExpressionInterfaceName(); - } - - if (typeRef.TypeId == InputTypeTypeId) - { - return GetInputTypeEnumName(); - } - - if (typeRef.TypeId == InteractionInputTypeId) - { - return GetInteractionInputInterfaceName(); - } - - if (typeRef.TypeId == InteractionInputCollectionTypeId) - { - return GetInteractionInputCollectionClassName(); - } - - // Check for wrapper class first (handles custom types like resource builders) - if (_wrapperClassNames.TryGetValue(typeRef.TypeId, out var wrapperClassName)) - { - return GetInterfaceName(wrapperClassName); - } - - var mappedType = typeRef.Category switch - { - AtsTypeCategory.Primitive => MapPrimitiveType(typeRef.TypeId), - AtsTypeCategory.Enum => MapEnumType(typeRef.TypeId), - AtsTypeCategory.Handle => GetWrapperOrHandleName(typeRef.TypeId), - AtsTypeCategory.Dto => GetDtoInterfaceName(typeRef.TypeId), - AtsTypeCategory.Callback => "Function", // Callbacks handled separately with full signature - AtsTypeCategory.Array => $"{MapTypeRefToTypeScript(typeRef.ElementType)}[]", - AtsTypeCategory.List => $"AspireList<{MapTypeRefToTypeScript(typeRef.ElementType)}>", - AtsTypeCategory.Dict => typeRef.IsReadOnly - ? $"Record<{MapTypeRefToTypeScript(typeRef.KeyType)}, {MapTypeRefToTypeScript(typeRef.ValueType)}>" - : $"AspireDict<{MapTypeRefToTypeScript(typeRef.KeyType)}, {MapTypeRefToTypeScript(typeRef.ValueType)}>", - AtsTypeCategory.Union => MapUnionTypeToTypeScript(typeRef), - AtsTypeCategory.Unknown => "any", // Unknown types use 'any' since they're not in the ATS universe - _ => "any" // Fallback for any unhandled categories - }; - return ApplyNullableType(typeRef, mappedType); - } - - private static string ApplyNullableType(AtsTypeRef typeRef, string mappedType) - { - if (typeRef.IsNullable != true || typeRef.Category is not (AtsTypeCategory.Primitive or AtsTypeCategory.Enum)) - { - return mappedType; - } - - return typeRef.TypeId is AtsConstants.Void or AtsConstants.Any or AtsConstants.CancellationToken - ? mappedType - : $"{mappedType} | null"; - } - - private string MapDtoPropertyTypeToTypeScript(AtsTypeRef? typeRef) - { - if (typeRef is null) - { - return "unknown"; - } - - return typeRef.Category switch - { - AtsTypeCategory.Array or AtsTypeCategory.List => $"{MapDtoPropertyTypeToTypeScript(typeRef.ElementType)}[]", - AtsTypeCategory.Dict => $"Record<{MapDtoPropertyTypeToTypeScript(typeRef.KeyType)}, {MapDtoPropertyTypeToTypeScript(typeRef.ValueType)}>", - AtsTypeCategory.Union => MapDtoUnionTypeToTypeScript(typeRef), - _ => MapTypeRefToTypeScript(typeRef) - }; - } - - private string MapDtoUnionTypeToTypeScript(AtsTypeRef typeRef) - { - if (typeRef.UnionTypes is null || typeRef.UnionTypes.Count == 0) - { - return "unknown"; - } - - var memberTypes = typeRef.UnionTypes - .Select(MapDtoPropertyTypeToTypeScript) - .Distinct(); - - return string.Join(" | ", memberTypes); - } - - /// - /// Maps primitive type IDs to TypeScript types. - /// - private static string MapPrimitiveType(string typeId) => typeId switch - { - AtsConstants.String or AtsConstants.Char => "string", - AtsConstants.Number => "number", - AtsConstants.Boolean => "boolean", - AtsConstants.Void => "void", - AtsConstants.Any => "any", - AtsConstants.DateTime or AtsConstants.DateTimeOffset or - AtsConstants.DateOnly or AtsConstants.TimeOnly => "string", - AtsConstants.TimeSpan => "number", - AtsConstants.Guid or AtsConstants.Uri => "string", - AtsConstants.CancellationToken => GetCancellationTokenInterfaceName(), - _ => typeId - }; - - /// - /// Maps an enum type ID to the generated TypeScript enum name. - /// Throws if the enum type wasn't collected during scanning. - /// - private string MapEnumType(string typeId) - { - if (!_enumTypeNames.TryGetValue(typeId, out var enumName)) - { - throw new InvalidOperationException( - $"Enum type '{typeId}' was not found in the scanned enum types. " + - $"This indicates the enum type was not discovered during assembly scanning."); - } - return enumName; - } - - /// - /// Maps a union type to TypeScript union syntax (T1 | T2 | ...). - /// - private string MapUnionTypeToTypeScript(AtsTypeRef typeRef) - { - if (typeRef.UnionTypes == null || typeRef.UnionTypes.Count == 0) - { - return "unknown"; - } - - var memberTypes = typeRef.UnionTypes - .Select(MapTypeRefToTypeScript) - .Distinct(); - - return string.Join(" | ", memberTypes); - } - - /// - /// Gets the wrapper class name or handle type name for a handle type ID. - /// Prefers wrapper class if one exists, otherwise generates a handle type name. - /// - private string GetWrapperOrHandleName(string typeId) - { - if (_wrapperClassNames.TryGetValue(typeId, out var wrapperClassName)) - { - return wrapperClassName; - } - return GetHandleTypeName(typeId); - } - - /// - /// Gets a TypeScript interface name for a DTO type. - /// - private static string GetDtoInterfaceName(string typeId) - { - return ExtractSimpleTypeName(typeId); - } - - /// - /// Maps a user-supplied input type to TypeScript. - /// For interface handle types, generated APIs accept any handle-bearing wrapper instance. - /// For cancellation tokens, generated APIs accept either an AbortSignal or a transport-safe CancellationToken. - /// - /// - /// Handle types are widened to accept Awaitable<T> so callers can pass un-awaited - /// fluent chains directly. Examples: - /// - /// // Input: RedisResource handle type - /// // Output: "Awaitable<RedisResource>" - /// - /// // Input: Union of string | RedisResource - /// // Output: "string | Awaitable<RedisResource>" - /// - /// // Input: CancellationToken type - /// // Output: "AbortSignal | CancellationToken" - /// - /// // Input: plain string type - /// // Output: "string" - /// - /// - private string MapInputTypeToTypeScript(AtsTypeRef? typeRef) - { - if (typeRef?.Category == AtsTypeCategory.Union) - { - return MapInputUnionTypeToTypeScript(typeRef); - } - - if (IsInterfaceHandleType(typeRef)) - { - if (TryMapInterfaceInputTypeToTypeScript(typeRef!) is { } interfaceInputType) - { - return $"Awaitable<{interfaceInputType}>"; - } - - var handleName = GetHandleReferenceInterfaceName(); - return $"Awaitable<{handleName}>"; - } - - if (IsHandleType(typeRef) && _wrapperClassNames.TryGetValue(typeRef!.TypeId, out var className)) - { - var ifaceName = GetInterfaceName(className); - return $"Awaitable<{ifaceName}>"; - } - - if (typeRef?.TypeId == InteractionInputCollectionTypeId) - { - return $"Awaitable<{GetInteractionInputCollectionClassName()}>"; - } - - if (IsCancellationTokenType(typeRef)) - { - return $"AbortSignal | {GetCancellationTokenInterfaceName()}"; - } - - return MapTypeRefToTypeScript(typeRef); - } - - private string MapInputUnionTypeToTypeScript(AtsTypeRef typeRef) - { - if (typeRef.UnionTypes == null || typeRef.UnionTypes.Count == 0) - { - throw new InvalidOperationException("Union input types must define at least one member type."); - } - - // Build union structurally: each member is mapped individually. - // Handle types become Awaitable, non-handle types pass through as-is. - var nonHandleTypes = new List(); - var handleTypeNames = new List(); - - foreach (var memberRef in typeRef.UnionTypes) - { - if (IsWidenedHandleType(memberRef)) - { - // Get the base type name without Awaitable wrapper for combining - var baseName = IsInterfaceHandleType(memberRef) && TryMapInterfaceInputTypeToTypeScript(memberRef) is { } expanded - ? expanded - : MapTypeRefToTypeScript(memberRef); - nonHandleTypes.Add(baseName); - handleTypeNames.Add(baseName); - } - else - { - nonHandleTypes.Add(MapInputTypeToTypeScript(memberRef)); - } - } - - var allBaseTypes = nonHandleTypes - .SelectMany(t => t.Split(" | ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)) - .Distinct(StringComparer.Ordinal) - .ToList(); - - if (handleTypeNames.Count > 0) - { - var handleUnion = string.Join(" | ", handleTypeNames - .SelectMany(t => t.Split(" | ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)) - .Distinct(StringComparer.Ordinal)); - return string.Join(" | ", allBaseTypes) + $" | Awaitable<{handleUnion}>"; - } - - return string.Join(" | ", allBaseTypes); - } - /// - /// Maps a parameter to its TypeScript type, handling callbacks specially. + /// Owns every TypeScript-specific resolution decision. Assigned per generation because it is + /// built from the context being generated; the canonical API exporter builds the same projector + /// from the same context so documentation cannot drift from emitted source. /// - private string MapParameterToTypeScript(AtsParameterInfo param) - { - if (param.IsCallback) - { - return GenerateCallbackTypeSignature(param.CallbackParameters, param.CallbackReturnType); - } - - return MapInputTypeToTypeScript(param.Type); - } + private TypeScriptApiProjector _projector = null!; private void WriteCapabilityDocComment( string indent, @@ -660,68 +316,9 @@ private static string ConvertAtsReferencesToJsDocLinks(string text) return builder.ToString(); } - private string? TryMapInterfaceInputTypeToTypeScript(AtsTypeRef typeRef) - { - List? assignableWrapperTypes = null; - - foreach (var candidateTypeRef in _typeRefsById.Values) - { - if (!IsAssignableToInterface(candidateTypeRef, typeRef.TypeId) || - !_wrapperClassNames.TryGetValue(candidateTypeRef.TypeId, out var wrapperClassName)) - { - continue; - } - - assignableWrapperTypes ??= []; - assignableWrapperTypes.Add(wrapperClassName); - } - - if (assignableWrapperTypes is not { Count: > 0 }) - { - return null; - } - - return string.Join(" | ", assignableWrapperTypes - .Distinct(StringComparer.Ordinal) - .OrderBy(static n => n, StringComparer.Ordinal)); - } - - private static bool IsAssignableToInterface(AtsTypeRef candidateTypeRef, string interfaceTypeId) - { - if (string.Equals(candidateTypeRef.TypeId, interfaceTypeId, StringComparison.Ordinal)) - { - return true; - } - - foreach (var implementedInterface in candidateTypeRef.ImplementedInterfaces) - { - if (IsAssignableToInterface(implementedInterface, interfaceTypeId)) - { - return true; - } - } - - return candidateTypeRef.BaseType is not null && IsAssignableToInterface(candidateTypeRef.BaseType, interfaceTypeId); - } - - /// - /// Checks if a type reference is an interface handle type. - /// Interface handles need union types to accept wrapper classes. - /// - private static bool IsInterfaceHandleType(AtsTypeRef? typeRef) - { - if (typeRef == null) - { - return false; - } - return typeRef.Category == AtsTypeCategory.Handle && typeRef.IsInterface; - } - - private static bool IsCancellationTokenType(AtsTypeRef? typeRef) => typeRef?.TypeId == AtsConstants.CancellationToken; - private static string GetRpcArgumentValueExpression(string parameterName, AtsTypeRef? typeRef) { - if (IsCancellationTokenType(typeRef)) + if (TypeScriptApiProjector.IsCancellationTokenType(typeRef)) { return $"CancellationToken.fromValue({parameterName})"; } @@ -783,7 +380,7 @@ private bool TryGetDtoCallbackMarshallingProperties(AtsTypeRef? typeRef, out Lis marshallingProperties = []; if (typeRef?.Category != AtsTypeCategory.Dto || - !_dtoTypesById.TryGetValue(typeRef.TypeId, out var dtoType)) + !_projector.DtoTypesById.TryGetValue(typeRef.TypeId, out var dtoType)) { return false; } @@ -798,7 +395,7 @@ private bool TryGetDtoCallbackMarshallingProperties(AtsTypeRef? typeRef, out Lis private bool RequiresDtoCallbackMarshalling(AtsTypeRef? typeRef, HashSet? visitedDtoTypeIds = null) { if (typeRef?.Category != AtsTypeCategory.Dto || - !_dtoTypesById.TryGetValue(typeRef.TypeId, out var dtoType)) + !_projector.DtoTypesById.TryGetValue(typeRef.TypeId, out var dtoType)) { return false; } @@ -846,16 +443,6 @@ public Dictionary GenerateDistributedApplication(AtsContext cont return files; } - /// - /// Gets a valid TypeScript method name from a capability method name. - /// Handles dotted names like "EnvironmentContext.resource" by extracting just the final part. - /// - private static string GetTypeScriptMethodName(string methodName) - { - var dotIndex = methodName.LastIndexOf('.'); - return dotIndex >= 0 ? methodName[(dotIndex + 1)..] : methodName; - } - /// /// Generates the aspire.mts SDK file with capability-based API. /// @@ -918,115 +505,20 @@ import type { """); WriteLine(); - var capabilities = context.Capabilities; + // Resolve every TypeScript-specific decision once. The canonical API exporter consumes the + // same projector, so documented signatures cannot drift from the signatures emitted here. + _projector = new TypeScriptApiProjector(context); + var resolved = _projector.Resolved; + var dtoTypes = context.DtoTypes; var enumTypes = context.EnumTypes; var exportedValues = context.ExportedValues; - // Get builder models (flattened - each builder has all its applicable capabilities) - var allBuilders = CreateBuilderModels(capabilities); - var entryPoints = GetEntryPointCapabilities(capabilities); - - // All builders (no special filtering) - var builders = allBuilders; - - // Entry point methods that don't extend any type go on AspireClient - var clientMethods = entryPoints - .Where(c => string.IsNullOrEmpty(c.TargetTypeId)) - .ToList(); - - // Collect all unique type IDs for handle type aliases - // Exclude DTO types - they have their own interfaces, not handle aliases - var dtoTypeIds = new HashSet(dtoTypes.Select(d => d.TypeId)); - var typeIds = new HashSet(); - foreach (var typeId in CollectAllReferencedTypes(capabilities).Keys) - { - if (!dtoTypeIds.Contains(typeId)) - { - typeIds.Add(typeId); - } - } - - // Ensure all builder type IDs have handle type aliases. - // CreateBuilderModels discovers additional resource types via CollectAllReferencedTypes - // (e.g. types that appear only in return types or parameters but aren't direct capability targets). - // Without this, the builder class references a handle type that was never declared. - foreach (var builder in builders) - { - if (!dtoTypeIds.Contains(builder.TypeId)) - { - typeIds.Add(builder.TypeId); - } - } - - // Separate builders into categories: - // 1. Resource builders: IResource*, ContainerResource, etc. - // 2. Type classes: everything else (context types, wrapper types) - var resourceBuilders = builders.Where(b => b.TargetType?.IsResourceBuilder == true).ToList(); - var typeClasses = builders.Where(b => b.TargetType?.IsResourceBuilder != true).ToList(); - - // Build wrapper class name mapping before DTO generation so callback - // properties can reference wrapper classes instead of raw handle aliases. - _wrapperClassNames.Clear(); - _typeRefsById.Clear(); - _typesWithPromiseWrappers.Clear(); - _generatedOptionsInterfaces.Clear(); - _optionsInterfacesToGenerate.Clear(); - _capabilityOptionsInterfaceMap.Clear(); - _handleDocumentationById.Clear(); - _dtoTypesById.Clear(); - - foreach (var dtoType in dtoTypes) - { - _dtoTypesById[dtoType.TypeId] = dtoType; - } - - foreach (var handleType in context.HandleTypes) - { - if (handleType.Documentation is not null) - { - _handleDocumentationById[handleType.AtsTypeId] = handleType.Documentation; - } - } - - foreach (var builder in resourceBuilders) - { - _wrapperClassNames[builder.TypeId] = builder.BuilderClassName; - if (builder.TargetType is { } targetType) - { - _typeRefsById[builder.TypeId] = targetType; - } - // All resource builders get Promise wrappers - _typesWithPromiseWrappers.Add(builder.TypeId); - } - foreach (var typeClass in typeClasses) - { - _wrapperClassNames[typeClass.TypeId] = DeriveClassName(typeClass.TypeId); - if (typeClass.TargetType is { } targetType) - { - _typeRefsById[typeClass.TypeId] = targetType; - } - // Type classes with methods get Promise wrappers - if (HasChainableMethods(typeClass)) - { - _typesWithPromiseWrappers.Add(typeClass.TypeId); - } - } - - // InteractionInputCollection is a hand-written base.mts type: its by-name accessors - // (value/get/required/requiredValue) are client-side conveniences, not ATS capabilities, so - // it is never registered as a generated type class. Register it as a promise-wrapper type so - // collection-returning getters (result.inputs(), validationContext.inputs(), command - // arguments()) emit the fluent InteractionInputCollectionPromise thenable instead of a bare - // Promise. That lets callers chain `await x.inputs().value("c")` - // without an intermediate await, matching the C#/Go/Java/Python surfaces. The wrapper - // (InteractionInputCollectionPromise / InteractionInputCollectionPromiseImpl) is hand-written - // in base.mts; it is intentionally absent from _wrapperClassNames so the getter impl keeps - // using the marshaller-based collection construction rather than a handle+Impl wrapper. - _typesWithPromiseWrappers.Add(InteractionInputCollectionTypeId); - // Note: ReferenceExpression is intentionally NOT added to _wrapperClassNames. - // It is a value type defined in base.mts with a private constructor and static factory, - // not a handle-based wrapper. It is handled via MapTypeRefToTypeScript instead. + var builders = resolved.Builders; + var resourceBuilders = resolved.ResourceBuilders; + var typeClasses = resolved.TypeClasses; + var clientMethods = resolved.ClientMethods; + var typeIds = resolved.HandleTypeIds; // Generate handle type aliases GenerateHandleTypeAliases(typeIds); @@ -1040,20 +532,6 @@ import type { // Generate exported immutable values GenerateExportedValues(exportedValues, dtoTypes.ToDictionary(dto => dto.TypeId, StringComparer.Ordinal)); - // Pre-scan all capabilities to collect options interfaces - // This must happen AFTER wrapper class names are populated so types resolve correctly - foreach (var builder in builders) - { - foreach (var cap in builder.Capabilities) - { - var (_, optionalParams) = SeparateParameters(cap.Parameters); - if (optionalParams.Count > 0 && !TryGetDirectOptionsParameter(optionalParams, out _)) - { - RegisterOptionsInterface(cap.CapabilityId, cap.MethodName, optionalParams); - } - } - } - // Generate collected options interfaces GenerateOptionsInterfaces(); @@ -1110,8 +588,8 @@ private void GenerateHandleTypeAliases(HashSet typeIds) foreach (var typeId in typeIds.OrderBy(t => t)) { - var handleName = GetHandleTypeName(typeId); - var description = GetTypeDescription(typeId); + var handleName = TypeScriptApiProjector.GetHandleTypeName(typeId); + var description = TypeScriptApiProjector.GetTypeDescription(typeId); WriteDocumentationComment(string.Empty, GetHandleDocumentation(typeId), description); // Internal type alias - not exported (users work with wrapper classes) WriteLine($"type {handleName} = Handle<'{typeId}'>;"); @@ -1121,7 +599,7 @@ private void GenerateHandleTypeAliases(HashSet typeIds) private AtsDocumentationInfo? GetHandleDocumentation(string typeId) { - return _handleDocumentationById.GetValueOrDefault(typeId); + return _projector.HandleDocumentationById.GetValueOrDefault(typeId); } /// @@ -1129,10 +607,8 @@ private void GenerateHandleTypeAliases(HashSet typeIds) /// private void GenerateEnumTypes(IReadOnlyList enumTypes) { - _enumTypeNames[InputTypeTypeId] = GetInputTypeEnumName(); - var generatedEnumTypes = enumTypes - .Where(enumType => enumType.TypeId != InputTypeTypeId) + .Where(enumType => enumType.TypeId != TypeScriptApiProjector.InputTypeTypeId) .ToList(); if (generatedEnumTypes.Count == 0) @@ -1147,9 +623,6 @@ private void GenerateEnumTypes(IReadOnlyList enumTypes) foreach (var enumType in generatedEnumTypes.OrderBy(e => e.Name)) { - // Track enum name for type mapping - _enumTypeNames[enumType.TypeId] = enumType.Name; - WriteDocumentationComment(string.Empty, enumType.Documentation, $"Enum type for {enumType.Name}"); WriteLine($"export enum {enumType.Name} {{"); @@ -1175,7 +648,7 @@ private void GenerateEnumTypes(IReadOnlyList enumTypes) private void GenerateDtoInterfaces(IReadOnlyList dtoTypes) { var generatedDtoTypes = dtoTypes - .Where(dto => dto.TypeId != InteractionInputTypeId) + .Where(dto => dto.TypeId != TypeScriptApiProjector.InteractionInputTypeId) .ToList(); if (generatedDtoTypes.Count == 0) @@ -1190,7 +663,7 @@ private void GenerateDtoInterfaces(IReadOnlyList dtoTypes) foreach (var dto in generatedDtoTypes.OrderBy(d => d.Name)) { - var interfaceName = GetDtoInterfaceName(dto.TypeId); + var interfaceName = TypeScriptApiProjector.GetDtoInterfaceName(dto.TypeId); WriteDocumentationComment(string.Empty, dto.Documentation, dto.Description ?? $"DTO interface for {dto.Name}"); WriteLine($"export interface {interfaceName} {{"); @@ -1198,11 +671,11 @@ private void GenerateDtoInterfaces(IReadOnlyList dtoTypes) foreach (var prop in dto.Properties) { var tsType = prop.IsCallback - ? GenerateCallbackTypeSignature(prop.CallbackParameters, prop.CallbackReturnType) - : MapDtoPropertyTypeToTypeScript(prop.Type); + ? _projector.GenerateCallbackTypeSignature(prop.CallbackParameters, prop.CallbackReturnType) + : _projector.MapDtoPropertyTypeToTypeScript(prop.Type); // All DTO properties are optional in TypeScript to allow partial objects // Convert PascalCase to camelCase for TypeScript - var propName = ToCamelCase(prop.Name); + var propName = TypeScriptApiProjector.ToCamelCase(prop.Name); WriteDocumentationComment(" ", prop.Documentation, prop.Description); WriteLine($" {propName}?: {tsType};"); } @@ -1258,7 +731,7 @@ private void WriteTypeScriptExportedValueChildren( WriteDocumentationComment(indent, valueInfo.Documentation, valueInfo.Description); var literal = RenderTypeScriptExportedValue(valueInfo.Value, valueInfo.Type, dtoTypesById); - var exportedType = MapTypeRefToTypeScript(valueInfo.Type); + var exportedType = _projector.MapTypeRefToTypeScript(valueInfo.Type); var needsCast = valueInfo.Type.Category is not AtsTypeCategory.Primitive; var expression = needsCast ? $"{literal} as {exportedType}" : literal; WriteLine($"{indent}export const {name} = {expression};"); @@ -1310,7 +783,7 @@ private string RenderTypeScriptDtoValue( continue; } - members.Add($"{ToCamelCase(property.Name)}: {RenderTypeScriptExportedValue(propertyValue, property.Type, dtoTypesById)}"); + members.Add($"{TypeScriptApiProjector.ToCamelCase(property.Name)}: {RenderTypeScriptExportedValue(propertyValue, property.Type, dtoTypesById)}"); } return "{ " + string.Join(", ", members) + " }"; @@ -1339,407 +812,51 @@ private static ExportedValueTreeNode BuildExportedValueTree(IReadOnlyList - /// Converts a PascalCase name to camelCase. - /// - private static string ToCamelCase(string name) - { - if (string.IsNullOrEmpty(name)) - { - return name; - } - if (char.IsLower(name[0])) - { - return name; - } - return char.ToLowerInvariant(name[0]) + name[1..]; - } - - /// - /// Converts a camelCase name to PascalCase. - /// - private static string ToPascalCase(string name) - { - if (string.IsNullOrEmpty(name)) - { - return name; - } - if (char.IsUpper(name[0])) - { - return name; - } - return char.ToUpperInvariant(name[0]) + name[1..]; - } - - /// - /// Gets the options interface name for a method. - /// Strips any type prefix (e.g., "TypeName.methodName" -> "MethodName"). - /// - private static string GetOptionsInterfaceName(string methodName) - { - // Strip type prefix if present (e.g., "EndpointReference.getExpression" -> "getExpression") - var simpleName = methodName.Contains('.') - ? methodName[(methodName.LastIndexOf('.') + 1)..] - : methodName; - return $"{ToPascalCase(simpleName)}Options"; - } - - /// - /// Gets the options interface name for a specific capability, accounting for type conflicts. - /// Falls back to the default method-name-based interface if no specific mapping exists. - /// - private string ResolveOptionsInterfaceName(AtsCapabilityInfo capability) - { - if (_capabilityOptionsInterfaceMap.TryGetValue(capability.CapabilityId, out var interfaceName)) - { - return interfaceName; - } - return GetOptionsInterfaceName(capability.MethodName); - } - - /// - /// Separates parameters into required and optional lists. - /// Required = not optional and not nullable. - /// - private static (List Required, List Optional) SeparateParameters( - IEnumerable parameters) - { - var required = new List(); - var optional = new List(); - - foreach (var param in parameters) - { - if (param.IsOptional || param.IsNullable) - { - optional.Add(param); - } - else - { - required.Add(param); - } - } - - return (required, optional); - } - - private static bool TryGetDirectOptionsParameter(List optionalParams, out AtsParameterInfo? directOptionsParam) - // A trailing cancellation token is rendered as its own parameter (see - // GetTrailingCancellationTokenParameter), so it is ignored when deciding whether the lone - // "options" DTO can be threaded directly instead of wrapped in a generated options object. - => AtsOptionsFlattening.TryGetDirectOptionsParameter( - optionalParams, - p => IsCancellationTokenType(p.Type), - cancellationTokenIsSeparateParameter: true, - out directOptionsParam); - - /// - /// When the options DTO is threaded directly (see ), - /// returns the trailing cancellation token optional parameter (if any) so it can be appended to - /// the generated method as its own argument rather than being folded into a generated options bag. - /// - private static AtsParameterInfo? GetTrailingCancellationTokenParameter(List optionalParams) - { - if (!TryGetDirectOptionsParameter(optionalParams, out _)) - { - return null; - } - - return optionalParams.FirstOrDefault(p => IsCancellationTokenType(p.Type)); - } - - /// - /// Registers an options interface to be generated later. - /// Uses method name to create the interface name. When methods share a name but have - /// incompatible callback parameter types, separate options interfaces are created with - /// numeric suffixes (e.g., RunAsEmulatorOptions, RunAsEmulator1Options). - /// - private void RegisterOptionsInterface(string capabilityId, string methodName, List optionalParams) - { - if (optionalParams.Count == 0) - { - return; - } - - var baseInterfaceName = GetOptionsInterfaceName(methodName); - - // Check if an existing interface with this name is compatible - if (_optionsInterfacesToGenerate.TryGetValue(baseInterfaceName, out var existingParams)) - { - if (AreOptionsCompatible(existingParams, optionalParams)) - { - // Compatible - merge any new parameters and share the interface - var existingNames = new HashSet(existingParams.Select(p => p.Name)); - foreach (var param in optionalParams) - { - if (existingNames.Add(param.Name)) - { - existingParams.Add(param); - } - } - _capabilityOptionsInterfaceMap[capabilityId] = baseInterfaceName; - return; - } - - // Incompatible - find or create a suffixed interface - for (var suffix = 1; ; suffix++) - { - var suffixedName = GetOptionsInterfaceName($"{methodName}{suffix}"); - if (!_optionsInterfacesToGenerate.TryGetValue(suffixedName, out var suffixedParams)) - { - // Create a new interface with this suffix - _generatedOptionsInterfaces.Add(suffixedName); - _optionsInterfacesToGenerate[suffixedName] = [.. optionalParams]; - _capabilityOptionsInterfaceMap[capabilityId] = suffixedName; - return; - } - - if (AreOptionsCompatible(suffixedParams, optionalParams)) - { - // Compatible with this suffixed interface - share it - var existingNames2 = new HashSet(suffixedParams.Select(p => p.Name)); - foreach (var param in optionalParams) - { - if (existingNames2.Add(param.Name)) - { - suffixedParams.Add(param); - } - } - _capabilityOptionsInterfaceMap[capabilityId] = suffixedName; - return; - } - } - } - else - { - // First registration - create the interface - _generatedOptionsInterfaces.Add(baseInterfaceName); - _optionsInterfacesToGenerate[baseInterfaceName] = [.. optionalParams]; - _capabilityOptionsInterfaceMap[capabilityId] = baseInterfaceName; - } - } - - /// - /// Checks whether two sets of optional parameters are compatible for sharing an options interface. - /// Parameters with the same name must have the same type (including callback parameter types). - /// - private static bool AreOptionsCompatible(List existing, List candidate) - { - foreach (var param in candidate) - { - var match = existing.FirstOrDefault(p => p.Name == param.Name); - if (match is null) - { - continue; // New parameter, no conflict - } - - // Same name - check type compatibility - if (!AreParameterTypesEqual(match, param)) - { - return false; - } - } - return true; - } - - /// - /// Checks whether two parameter infos have the same type (including callback types). - /// - private static bool AreParameterTypesEqual(AtsParameterInfo a, AtsParameterInfo b) - { - // Compare base type - var aTypeId = a.Type?.TypeId; - var bTypeId = b.Type?.TypeId; - if (!string.Equals(aTypeId, bTypeId, StringComparison.Ordinal)) - { - return false; - } - - // Compare callback parameter types - if (a.IsCallback != b.IsCallback) - { - return false; - } - - if (a.IsCallback && b.IsCallback) - { - var aCallbackParams = a.CallbackParameters ?? []; - var bCallbackParams = b.CallbackParameters ?? []; - - if (aCallbackParams.Count != bCallbackParams.Count) - { - return false; - } - - for (var i = 0; i < aCallbackParams.Count; i++) - { - if (!string.Equals(aCallbackParams[i].Type.TypeId, bCallbackParams[i].Type.TypeId, StringComparison.Ordinal)) - { - return false; - } - } - - // Compare callback return types - var aReturnTypeId = a.CallbackReturnType?.TypeId; - var bReturnTypeId = b.CallbackReturnType?.TypeId; - if (!string.Equals(aReturnTypeId, bReturnTypeId, StringComparison.Ordinal)) - { - return false; - } - } - - return true; - } - - /// - /// Generates all collected options interfaces. - /// - private void GenerateOptionsInterfaces() - { - if (_optionsInterfacesToGenerate.Count == 0) - { - return; - } - - WriteLine("// ============================================================================"); - WriteLine("// Options Interfaces"); - WriteLine("// ============================================================================"); - WriteLine(); - - foreach (var (interfaceName, optionalParams) in _optionsInterfacesToGenerate.OrderBy(kvp => kvp.Key)) - { - WriteLine($"export interface {interfaceName} {{"); - foreach (var param in optionalParams) - { - var tsType = MapParameterToTypeScript(param); - WriteDocumentationComment(" ", param.Documentation); - WriteLine($" {param.Name}?: {tsType};"); - } - WriteLine("}"); - WriteLine(); - } - } - - private static string GetTypeDescription(string typeId) - { - var typeName = ExtractSimpleTypeName(typeId); - return $"Handle to {typeName}"; - } - - private string BuildPublicParameterList( - List requiredParams, - bool hasOptionals, - string optionsInterfaceName, - string optionsParameterName = "options", - AtsParameterInfo? trailingCancellationToken = null) - { - var publicParamDefs = new List(); - foreach (var param in requiredParams) - { - var tsType = MapParameterToTypeScript(param); - publicParamDefs.Add($"{param.Name}: {tsType}"); - } - if (hasOptionals) - { - publicParamDefs.Add($"{optionsParameterName}?: {optionsInterfaceName}"); - } - if (trailingCancellationToken is not null) - { - publicParamDefs.Add($"{trailingCancellationToken.Name}?: {MapParameterToTypeScript(trailingCancellationToken)}"); - } - - return string.Join(", ", publicParamDefs); - } - - private static string GetPublicOptionsParameterName( - IReadOnlyList userParams, - bool hasOptionals, - bool hasDirectOptionsParameter) - { - if (!hasOptionals || hasDirectOptionsParameter) - { - return "options"; - } - - if (!userParams.Any(p => string.Equals(p.Name, "options", StringComparison.Ordinal))) - { - return "options"; - } - - var candidate = "optionsBag"; - while (userParams.Any(p => string.Equals(p.Name, candidate, StringComparison.Ordinal))) - { - candidate = $"_{candidate}"; - } - - return candidate; - } - - private static bool IsGetterOnlyProperty(AtsCapabilityInfo? getter, AtsCapabilityInfo? setter) => getter is not null && setter is null; - - private string GetGetterOnlyPropertyReturnType(AtsTypeRef? typeRef) - { - if (typeRef == null) - { - return "unknown"; - } - - if (IsDictionaryType(typeRef)) - { - var keyType = typeRef.KeyType != null ? MapTypeRefToTypeScript(typeRef.KeyType) : "string"; - var valueType = typeRef.ValueType != null ? MapTypeRefToTypeScript(typeRef.ValueType) : "unknown"; - return $"AspireDict<{keyType}, {valueType}>"; - } - - if (IsListType(typeRef)) - { - var elementType = typeRef.ElementType != null ? MapTypeRefToTypeScript(typeRef.ElementType) : "unknown"; - return $"AspireList<{elementType}>"; + current.Value = exportedValue; } - return MapTypeRefToTypeScript(typeRef); + return root; } - private bool TryGetPromiseWrapperType(AtsTypeRef? typeRef, out string promiseInterfaceName, out string promiseImplementationClassName) + /// + /// Generates all collected options interfaces. + /// + private void GenerateOptionsInterfaces() { - if (typeRef?.TypeId is { } typeId && _typesWithPromiseWrappers.Contains(typeId)) + if (_projector.OptionsInterfacesToGenerate.Count == 0) { - var className = GetConcreteClassName(typeId); - promiseInterfaceName = GetPromiseInterfaceName(className); - promiseImplementationClassName = GetImplementationPromiseClassName(className); - return true; + return; } - promiseInterfaceName = string.Empty; - promiseImplementationClassName = string.Empty; - return false; - } + WriteLine("// ============================================================================"); + WriteLine("// Options Interfaces"); + WriteLine("// ============================================================================"); + WriteLine(); - private string GetGetterOnlyPropertyMethodReturnType(AtsTypeRef? typeRef) - { - if (TryGetPromiseWrapperType(typeRef, out var promiseInterfaceName, out _)) + foreach (var (interfaceName, optionalParams) in _projector.OptionsInterfacesToGenerate.OrderBy(kvp => kvp.Key)) { - return promiseInterfaceName; + WriteLine($"export interface {interfaceName} {{"); + foreach (var param in optionalParams) + { + var tsType = _projector.MapParameterToTypeScript(param); + WriteDocumentationComment(" ", param.Documentation); + WriteLine($" {param.Name}?: {tsType};"); + } + WriteLine("}"); + WriteLine(); } - - return $"Promise<{GetGetterOnlyPropertyReturnType(typeRef)}>"; } private void GenerateGetterOnlyPropertyPromiseSignature(string propertyName, AtsCapabilityInfo getter) { - var returnType = GetGetterOnlyPropertyMethodReturnType(getter.ReturnType); + var returnType = _projector.GetGetterOnlyPropertyMethodReturnType(getter.ReturnType); WriteCapabilityDocComment(" ", getter); WriteLine($" {propertyName}(): {returnType};"); } private void GenerateInterfaceProperty(string propertyName, AtsCapabilityInfo? getter, AtsCapabilityInfo? setter) { - if (IsGetterOnlyProperty(getter, setter)) + if (TypeScriptApiProjector.IsGetterOnlyProperty(getter, setter)) { GenerateGetterOnlyPropertyPromiseSignature(propertyName, getter!); return; @@ -1747,18 +864,18 @@ private void GenerateInterfaceProperty(string propertyName, AtsCapabilityInfo? g if (getter?.ReturnType is { } returnType) { - if (IsDictionaryType(returnType)) + if (TypeScriptApiProjector.IsDictionaryType(returnType)) { - var keyType = returnType.KeyType != null ? MapTypeRefToTypeScript(returnType.KeyType) : "string"; - var valueType = returnType.ValueType != null ? MapTypeRefToTypeScript(returnType.ValueType) : "unknown"; + var keyType = returnType.KeyType != null ? _projector.MapTypeRefToTypeScript(returnType.KeyType) : "string"; + var valueType = returnType.ValueType != null ? _projector.MapTypeRefToTypeScript(returnType.ValueType) : "unknown"; WritePropertyDocComment(" ", getter, setter); WriteLine($" readonly {propertyName}: AspireDict<{keyType}, {valueType}>;"); return; } - if (IsListType(returnType)) + if (TypeScriptApiProjector.IsListType(returnType)) { - var elementType = returnType.ElementType != null ? MapTypeRefToTypeScript(returnType.ElementType) : "unknown"; + var elementType = returnType.ElementType != null ? _projector.MapTypeRefToTypeScript(returnType.ElementType) : "unknown"; WritePropertyDocComment(" ", getter, setter); WriteLine($" readonly {propertyName}: AspireList<{elementType}>;"); return; @@ -1770,13 +887,13 @@ private void GenerateInterfaceProperty(string propertyName, AtsCapabilityInfo? g if (getter != null) { - if (TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out _)) + if (_projector.TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out _)) { WriteLine($" get: () => {promiseInterfaceName};"); } else { - var returnTypeName = MapTypeRefToTypeScript(getter.ReturnType); + var returnTypeName = _projector.MapTypeRefToTypeScript(getter.ReturnType); WriteLine($" get: () => Promise<{returnTypeName}>;"); } } @@ -1786,7 +903,7 @@ private void GenerateInterfaceProperty(string propertyName, AtsCapabilityInfo? g var valueParam = setter.Parameters.FirstOrDefault(p => p.Name == "value"); if (valueParam != null) { - var valueType = MapInputTypeToTypeScript(valueParam.Type); + var valueType = _projector.MapInputTypeToTypeScript(valueParam.Type); WriteLine($" set: (value: {valueType}) => Promise;"); } } @@ -1794,21 +911,9 @@ private void GenerateInterfaceProperty(string propertyName, AtsCapabilityInfo? g WriteLine(" };"); } - private string GetBuilderPromiseInterfaceForMethod(BuilderModel builder, AtsCapabilityInfo capability) - { - if (capability.ReturnsBuilder && capability.ReturnType?.TypeId != null && - !string.Equals(capability.ReturnType.TypeId, builder.TypeId, StringComparison.Ordinal) && - !string.Equals(capability.ReturnType.TypeId, capability.TargetTypeId, StringComparison.Ordinal)) - { - return GetPublicPromiseInterfaceName(capability.ReturnType.TypeId); - } - - return GetPromiseInterfaceName(builder.BuilderClassName); - } - private void GenerateBuilderInterface(BuilderModel builder) { - var interfaceName = GetInterfaceName(builder.BuilderClassName); + var interfaceName = TypeScriptApiProjector.GetInterfaceName(builder.BuilderClassName); WriteLine("// ============================================================================"); WriteLine($"// {interfaceName}"); @@ -1822,7 +927,7 @@ private void GenerateBuilderInterface(BuilderModel builder) var setters = builder.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); if (getters.Count > 0 || setters.Count > 0) { - var properties = GroupPropertiesByName(getters, setters); + var properties = TypeScriptApiProjector.GroupPropertiesByName(getters, setters); foreach (var prop in properties) { GenerateInterfaceProperty(prop.PropertyName, prop.Getter, prop.Setter); @@ -1835,29 +940,29 @@ private void GenerateBuilderInterface(BuilderModel builder) { var targetParamName = capability.TargetParameterName ?? "builder"; var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var publicParamsString = BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: GetTrailingCancellationTokenParameter(optionalParams)); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var publicParamsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); var hasNonBuilderReturn = !capability.ReturnsBuilder && capability.ReturnType != null; WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? "options" : null); if (hasNonBuilderReturn) { - if (TryGetPromiseWrapperType(capability.ReturnType, out var promiseInterfaceName, out _)) + if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var promiseInterfaceName, out _)) { WriteLine($" {capability.MethodName}({publicParamsString}): {promiseInterfaceName};"); } else { - var returnType = MapTypeRefToTypeScript(capability.ReturnType); + var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); WriteLine($" {capability.MethodName}({publicParamsString}): Promise<{returnType}>;"); } } else { - WriteLine($" {capability.MethodName}({publicParamsString}): {GetBuilderPromiseInterfaceForMethod(builder, capability)};"); + WriteLine($" {capability.MethodName}({publicParamsString}): {_projector.GetBuilderPromiseInterfaceForMethod(builder, capability)};"); } } @@ -1872,8 +977,8 @@ private void GenerateBuilderPromiseInterface(BuilderModel builder) c.CapabilityKind != AtsCapabilityKind.PropertySetter).ToList(); var getters = builder.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); var setters = builder.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); - var getterOnlyProperties = GroupPropertiesByName(getters, setters) - .Where(p => IsGetterOnlyProperty(p.Getter, p.Setter)) + var getterOnlyProperties = TypeScriptApiProjector.GroupPropertiesByName(getters, setters) + .Where(p => TypeScriptApiProjector.IsGetterOnlyProperty(p.Getter, p.Setter)) .ToList(); if (capabilities.Count == 0 && getterOnlyProperties.Count == 0) @@ -1881,8 +986,8 @@ private void GenerateBuilderPromiseInterface(BuilderModel builder) return; } - var interfaceName = GetInterfaceName(builder.BuilderClassName); - var promiseInterfaceName = GetPromiseInterfaceName(builder.BuilderClassName); + var interfaceName = TypeScriptApiProjector.GetInterfaceName(builder.BuilderClassName); + var promiseInterfaceName = TypeScriptApiProjector.GetPromiseInterfaceName(builder.BuilderClassName); WriteLine($"export interface {promiseInterfaceName} extends PromiseLike<{interfaceName}> {{"); @@ -1895,29 +1000,29 @@ private void GenerateBuilderPromiseInterface(BuilderModel builder) { var targetParamName = capability.TargetParameterName ?? "builder"; var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var paramsString = BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: GetTrailingCancellationTokenParameter(optionalParams)); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); var hasNonBuilderReturn = !capability.ReturnsBuilder && capability.ReturnType != null; WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? "options" : null); if (hasNonBuilderReturn) { - if (TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out _)) + if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out _)) { WriteLine($" {capability.MethodName}({paramsString}): {returnPromiseInterfaceName};"); } else { - var returnType = MapTypeRefToTypeScript(capability.ReturnType); + var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); WriteLine($" {capability.MethodName}({paramsString}): Promise<{returnType}>;"); } } else { - WriteLine($" {capability.MethodName}({paramsString}): {GetBuilderPromiseInterfaceForMethod(builder, capability)};"); + WriteLine($" {capability.MethodName}({paramsString}): {_projector.GetBuilderPromiseInterfaceForMethod(builder, capability)};"); } } @@ -1929,36 +1034,36 @@ private void GenerateTypeClassInterfaceMethod(string className, AtsCapabilityInf { var methodName = !string.IsNullOrEmpty(capability.OwningTypeName) && capability.MethodName.Contains('.') ? capability.MethodName[(capability.MethodName.LastIndexOf('.') + 1)..] - : GetTypeScriptMethodName(capability.MethodName); + : TypeScriptApiProjector.GetTypeScriptMethodName(capability.MethodName); var targetParamName = capability.TargetParameterName ?? "context"; var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var paramsString = BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: GetTrailingCancellationTokenParameter(optionalParams)); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); var isVoid = capability.ReturnType == null || capability.ReturnType.TypeId == AtsConstants.Void; WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? "options" : null); - if (capability.ReturnType != null && _typesWithPromiseWrappers.Contains(capability.ReturnType.TypeId)) + if (capability.ReturnType != null && _projector.TypesWithPromiseWrappers.Contains(capability.ReturnType.TypeId)) { - WriteLine($" {methodName}({paramsString}): {GetPublicPromiseInterfaceName(capability.ReturnType.TypeId)};"); + WriteLine($" {methodName}({paramsString}): {_projector.GetPublicPromiseInterfaceName(capability.ReturnType.TypeId)};"); } else if (isVoid) { - WriteLine($" {methodName}({paramsString}): {GetPromiseInterfaceName(className)};"); + WriteLine($" {methodName}({paramsString}): {TypeScriptApiProjector.GetPromiseInterfaceName(className)};"); } else { - var returnType = MapTypeRefToTypeScript(capability.ReturnType); + var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); WriteLine($" {methodName}({paramsString}): Promise<{returnType}>;"); } } private void GenerateTypeClassInterface(BuilderModel model) { - var className = DeriveClassName(model.TypeId); - var interfaceName = GetInterfaceName(className); + var className = TypeScriptApiProjector.DeriveClassName(model.TypeId); + var interfaceName = TypeScriptApiProjector.GetInterfaceName(className); WriteLine("// ============================================================================"); WriteLine($"// {interfaceName}"); @@ -1975,9 +1080,9 @@ private void GenerateTypeClassInterface(BuilderModel model) var standardMethods = contextMethods.Concat(otherMethods).ToList(); var hasMethods = standardMethods.Count > 0; - var properties = GroupPropertiesByName(getters, setters); + var properties = TypeScriptApiProjector.GroupPropertiesByName(getters, setters); var getterOnlyProperties = properties - .Where(p => IsGetterOnlyProperty(p.Getter, p.Setter)) + .Where(p => TypeScriptApiProjector.IsGetterOnlyProperty(p.Getter, p.Setter)) .ToList(); foreach (var prop in properties) { @@ -1997,7 +1102,7 @@ private void GenerateTypeClassInterface(BuilderModel model) return; } - var promiseInterfaceName = GetPromiseInterfaceName(className); + var promiseInterfaceName = TypeScriptApiProjector.GetPromiseInterfaceName(className); WriteLine($"export interface {promiseInterfaceName} extends PromiseLike<{interfaceName}> {{"); foreach (var prop in getterOnlyProperties) { @@ -2016,14 +1121,14 @@ private void GenerateBuilderClass(BuilderModel builder) GenerateBuilderInterface(builder); GenerateBuilderPromiseInterface(builder); - var implementationClassName = GetImplementationClassName(builder.BuilderClassName); + var implementationClassName = TypeScriptApiProjector.GetImplementationClassName(builder.BuilderClassName); WriteLine("// ============================================================================"); WriteLine($"// {implementationClassName}"); WriteLine("// ============================================================================"); WriteLine(); - var handleType = GetHandleTypeName(builder.TypeId); + var handleType = TypeScriptApiProjector.GetHandleTypeName(builder.TypeId); // Generate builder class extending ResourceBuilderBase WriteDocumentationComment(string.Empty, GetHandleDocumentation(builder.TypeId)); @@ -2040,7 +1145,7 @@ private void GenerateBuilderClass(BuilderModel builder) var setters = builder.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); if (getters.Count > 0 || setters.Count > 0) { - var properties = GroupPropertiesByName(getters, setters); + var properties = TypeScriptApiProjector.GroupPropertiesByName(getters, setters); foreach (var prop in properties) { GeneratePropertyLikeObject(prop.PropertyName, prop.Getter, prop.Setter); @@ -2101,20 +1206,20 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); // Separate required and optional parameters - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsTypeName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var publicOptionsParamName = GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsTypeName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list for public method - var publicParamsString = BuildPublicParameterList(requiredParams, hasOptionals, optionsTypeName, publicOptionsParamName, GetTrailingCancellationTokenParameter(optionalParams)); + var publicParamsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsTypeName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); // Build parameter list for internal method (all params positional for callback registration) var internalParamDefs = new List(); foreach (var param in userParams) { - var tsType = MapParameterToTypeScript(param); + var tsType = _projector.MapParameterToTypeScript(param); var optional = param.IsOptional || param.IsNullable ? "?" : ""; internalParamDefs.Add($"{param.Name}{optional}: {tsType}"); } @@ -2133,25 +1238,25 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab !string.Equals(capability.ReturnType.TypeId, capability.TargetTypeId, StringComparison.Ordinal)) { returnTypeId = capability.ReturnType.TypeId; - returnClassName = _wrapperClassNames.GetValueOrDefault(returnTypeId) - ?? DeriveClassName(returnTypeId); + returnClassName = _projector.WrapperClassNames.GetValueOrDefault(returnTypeId) + ?? TypeScriptApiProjector.DeriveClassName(returnTypeId); } var returnHandle = capability.ReturnsBuilder - ? GetHandleTypeName(returnTypeId) + ? TypeScriptApiProjector.GetHandleTypeName(returnTypeId) : "void"; var returnsBuilder = capability.ReturnsBuilder; - var returnImplementationClassName = GetImplementationClassName(returnClassName); + var returnImplementationClassName = TypeScriptApiProjector.GetImplementationClassName(returnClassName); // Check if this method returns a non-builder, non-void type (e.g., getEndpoint returns EndpointReference) var hasNonBuilderReturn = !returnsBuilder && capability.ReturnType != null; if (hasNonBuilderReturn) { - if (TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) { var wrappedReturnTypeId = capability.ReturnType!.TypeId; - var wrappedReturnClassName = GetConcreteClassName(wrappedReturnTypeId); - var returnImplementationClassNameForWrapper = GetImplementationClassName(wrappedReturnClassName); - var returnHandleType = GetHandleTypeName(wrappedReturnTypeId); + var wrappedReturnClassName = _projector.GetConcreteClassName(wrappedReturnTypeId); + var returnImplementationClassNameForWrapper = TypeScriptApiProjector.GetImplementationClassName(wrappedReturnClassName); + var returnHandleType = TypeScriptApiProjector.GetHandleTypeName(wrappedReturnTypeId); WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? publicOptionsParamName : null); Write($" {methodName}("); @@ -2162,7 +1267,7 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } var callbackParamsForPromiseWrapper = userParams.Where(p => p.IsCallback).ToList(); @@ -2187,7 +1292,7 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab } // Generate a simple async method that returns the actual type - var returnType = MapTypeRefToTypeScript(capability.ReturnType); + var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? publicOptionsParamName : null); Write($" async {methodName}("); @@ -2198,7 +1303,7 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } // Handle callback registration if any @@ -2275,7 +1380,7 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab // Generate public fluent method (returns thenable wrapper) var promiseClass = $"{returnClassName}Promise"; - var promiseImplementationClass = GetImplementationPromiseClassName(returnClassName); + var promiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(returnClassName); WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? publicOptionsParamName : null); Write($" {methodName}("); Write(publicParamsString); @@ -2286,7 +1391,7 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } // Forward all params to internal method @@ -2335,7 +1440,7 @@ private void GeneratePromiseResolution(IReadOnlyList parameter continue; } - if (IsWidenedHandleType(param.Type)) + if (_projector.IsWidenedHandleType(param.Type)) { WriteLine($"{indent}{param.Name} = isPromiseLike({param.Name}) ? await {param.Name} : {param.Name};"); } @@ -2354,49 +1459,12 @@ private void GeneratePromiseResolution(IReadOnlyList parameter /// private void GeneratePromiseResolutionForParam(string paramName, AtsTypeRef? paramType, string indent = " ") { - if (IsWidenedHandleType(paramType)) + if (_projector.IsWidenedHandleType(paramType)) { WriteLine($"{indent}{paramName} = isPromiseLike({paramName}) ? await {paramName} : {paramName};"); } } - /// - /// Checks if a type was widened to accept Awaitable<T> in input position. - /// Must match the widening logic in MapInputTypeToTypeScript exactly. - /// - private bool IsWidenedHandleType(AtsTypeRef? typeRef) - { - if (typeRef == null) - { - return false; - } - - // Interface handles are always widened - if (IsInterfaceHandleType(typeRef)) - { - return true; - } - - // Concrete handles are only widened if they have a wrapper class name - // (excludes special types like ReferenceExpression that bypass widening) - if (IsHandleType(typeRef) && _wrapperClassNames.ContainsKey(typeRef.TypeId)) - { - return true; - } - - if (typeRef.TypeId == InteractionInputCollectionTypeId) - { - return true; - } - - if (typeRef.Category == AtsTypeCategory.Union && typeRef.UnionTypes is { Count: > 0 }) - { - return typeRef.UnionTypes.Any(IsWidenedHandleType); - } - - return false; - } - /// /// Generates promise resolution and args object construction in one step. /// This is the unified helper used by builder methods, type class methods, context methods, and wrapper methods. @@ -2531,7 +1599,7 @@ private void GenerateDtoCallbackPropertyAssignments( { if (marshallingProperty.IsCallback) { - var propertyName = ToCamelCase(marshallingProperty.Name); + var propertyName = TypeScriptApiProjector.ToCamelCase(marshallingProperty.Name); var callbackLocalName = GetDtoCallbackLocalName(dtoRpcLocalName, marshallingProperty.Name); WriteLine($"{indent}const {callbackLocalName} = {dtoRpcLocalName}.{propertyName};"); WriteLine($"{indent}if ({callbackLocalName} !== undefined) {{"); @@ -2558,7 +1626,7 @@ private void GenerateNestedDtoCallbackPropertyAssignments( return; } - var propertyName = ToCamelCase(dtoProperty.Name); + var propertyName = TypeScriptApiProjector.ToCamelCase(dtoProperty.Name); var dtoPropertyLocalName = GetDtoCallbackLocalName(dtoRpcLocalName, dtoProperty.Name); var nestedDtoRpcLocalName = $"{dtoPropertyLocalName}ForRpc"; @@ -2623,8 +1691,8 @@ private void GenerateThenableClass(BuilderModel builder) c.CapabilityKind != AtsCapabilityKind.PropertySetter).ToList(); var getters = builder.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); var setters = builder.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); - var getterOnlyProperties = GroupPropertiesByName(getters, setters) - .Where(p => IsGetterOnlyProperty(p.Getter, p.Setter)) + var getterOnlyProperties = TypeScriptApiProjector.GroupPropertiesByName(getters, setters) + .Where(p => TypeScriptApiProjector.IsGetterOnlyProperty(p.Getter, p.Setter)) .ToList(); if (capabilities.Count == 0 && getterOnlyProperties.Count == 0) @@ -2633,7 +1701,7 @@ private void GenerateThenableClass(BuilderModel builder) } var promiseClass = $"{builder.BuilderClassName}Promise"; - var promiseImplementationClass = GetImplementationPromiseClassName(builder.BuilderClassName); + var promiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(builder.BuilderClassName); WriteLine($"/**"); WriteLine($" * Thenable wrapper for {builder.BuilderClassName} that enables fluent chaining."); @@ -2657,9 +1725,9 @@ private void GenerateThenableClass(BuilderModel builder) foreach (var prop in getterOnlyProperties) { - var returnType = GetGetterOnlyPropertyMethodReturnType(prop.Getter!.ReturnType); + var returnType = _projector.GetGetterOnlyPropertyMethodReturnType(prop.Getter!.ReturnType); WriteLine($" {prop.PropertyName}(): {returnType} {{"); - if (TryGetPromiseWrapperType(prop.Getter!.ReturnType, out _, out var promiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(prop.Getter!.ReturnType, out _, out var promiseImplementationClassName)) { WriteLine($" return new {promiseImplementationClassName}(this._promise.then(obj => obj.{prop.PropertyName}()), this._client, false);"); } @@ -2681,17 +1749,17 @@ private void GenerateThenableClass(BuilderModel builder) var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); // Separate required and optional parameters - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsTypeName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var trailingCancellationToken = GetTrailingCancellationTokenParameter(optionalParams); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsTypeName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var trailingCancellationToken = TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams); // Build parameter list using options pattern var publicParamDefs = new List(); foreach (var param in requiredParams) { - var tsType = MapParameterToTypeScript(param); + var tsType = _projector.MapParameterToTypeScript(param); publicParamDefs.Add($"{param.Name}: {tsType}"); } if (hasOptionals) @@ -2700,7 +1768,7 @@ private void GenerateThenableClass(BuilderModel builder) } if (trailingCancellationToken is not null) { - publicParamDefs.Add($"{trailingCancellationToken.Name}?: {MapParameterToTypeScript(trailingCancellationToken)}"); + publicParamDefs.Add($"{trailingCancellationToken.Name}?: {_projector.MapParameterToTypeScript(trailingCancellationToken)}"); } var paramsString = string.Join(", ", publicParamDefs); @@ -2725,7 +1793,7 @@ private void GenerateThenableClass(BuilderModel builder) if (hasNonBuilderReturn) { - if (TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) { Write($" {methodName}("); Write(paramsString); @@ -2739,7 +1807,7 @@ private void GenerateThenableClass(BuilderModel builder) } // For non-builder returns, call the public method directly - var returnType = MapTypeRefToTypeScript(capability.ReturnType); + var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); Write($" {methodName}("); Write(paramsString); WriteLine($"): Promise<{returnType}> {{"); @@ -2758,10 +1826,10 @@ private void GenerateThenableClass(BuilderModel builder) !string.Equals(capability.ReturnType.TypeId, builder.TypeId, StringComparison.Ordinal) && !string.Equals(capability.ReturnType.TypeId, capability.TargetTypeId, StringComparison.Ordinal)) { - var returnClass = _wrapperClassNames.GetValueOrDefault(capability.ReturnType.TypeId) - ?? DeriveClassName(capability.ReturnType.TypeId); + var returnClass = _projector.WrapperClassNames.GetValueOrDefault(capability.ReturnType.TypeId) + ?? TypeScriptApiProjector.DeriveClassName(capability.ReturnType.TypeId); methodPromiseClass = $"{returnClass}Promise"; - methodPromiseImplementationClass = GetImplementationPromiseClassName(returnClass); + methodPromiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(returnClass); } Write($" {methodName}("); @@ -2827,17 +1895,17 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) var paramDefs = new List { "client: AspireClientRpc" }; foreach (var param in capability.Parameters) { - var tsType = MapParameterToTypeScript(param); + var tsType = _projector.MapParameterToTypeScript(param); var optional = param.IsOptional || param.IsNullable ? "?" : ""; paramDefs.Add($"{param.Name}{optional}: {tsType}"); } var paramsString = string.Join(", ", paramDefs); - var (requiredParams, optionalParams) = SeparateParameters(capability.Parameters); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(capability.Parameters); // Determine return type - check if return type has a Promise wrapper var capReturnTypeId = GetReturnTypeId(capability); - var returnPromiseWrapper = GetPromiseWrapperForReturnType(capability.ReturnType); + var returnPromiseWrapper = _projector.GetPromiseWrapperForReturnType(capability.ReturnType); // Generate JSDoc WriteCapabilityDocComment(string.Empty, capability); @@ -2846,11 +1914,11 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) if (returnPromiseWrapper != null && !string.IsNullOrEmpty(capReturnTypeId)) { // Return type has Promise wrapper - generate fluent function - var returnWrapperClass = _wrapperClassNames.GetValueOrDefault(capReturnTypeId) - ?? DeriveClassName(capReturnTypeId); - var returnWrapperImplementationClass = GetImplementationClassName(returnWrapperClass); - var returnPromiseImplementationClass = GetImplementationPromiseClassName(returnWrapperClass); - var handleType = GetHandleTypeName(capReturnTypeId); + var returnWrapperClass = _projector.WrapperClassNames.GetValueOrDefault(capReturnTypeId) + ?? TypeScriptApiProjector.DeriveClassName(capReturnTypeId); + var returnWrapperImplementationClass = TypeScriptApiProjector.GetImplementationClassName(returnWrapperClass); + var returnPromiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(returnWrapperClass); + var handleType = TypeScriptApiProjector.GetHandleTypeName(capReturnTypeId); Write($"export function {methodName}("); Write(paramsString); @@ -2860,7 +1928,7 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) // Resolve promise-like handle params foreach (var param in capability.Parameters) { - if (!param.IsCallback && IsWidenedHandleType(param.Type)) + if (!param.IsCallback && _projector.IsWidenedHandleType(param.Type)) { WriteLine($" {param.Name} = isPromiseLike({param.Name}) ? await {param.Name} : {param.Name};"); } @@ -2887,7 +1955,7 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) { // No Promise wrapper - return plain value var returnType = !string.IsNullOrEmpty(capReturnTypeId) - ? MapTypeRefToTypeScript(capability.ReturnType) + ? _projector.MapTypeRefToTypeScript(capability.ReturnType) : "void"; Write($"export async function {methodName}("); @@ -2896,7 +1964,7 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) // Resolve promise-like handle params foreach (var param in capability.Parameters) { - if (!param.IsCallback && IsWidenedHandleType(param.Type)) + if (!param.IsCallback && _projector.IsWidenedHandleType(param.Type)) { WriteLine($" {param.Name} = isPromiseLike({param.Name}) ? await {param.Name} : {param.Name};"); } @@ -2937,30 +2005,6 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) WriteLine(); } - private string GenerateCallbackTypeSignature(IReadOnlyList? callbackParameters, AtsTypeRef? callbackReturnType) - { - // Build parameter list - var paramList = new List(); - if (callbackParameters is not null) - { - foreach (var param in callbackParameters) - { - var tsType = MapTypeRefToTypeScript(param.Type); - paramList.Add($"{param.Name}: {tsType}"); - } - } - - var paramsString = paramList.Count > 0 ? string.Join(", ", paramList) : ""; - - // Determine return type - var returnType = callbackReturnType == null || callbackReturnType.TypeId == AtsConstants.Void - ? "void" - : MapTypeRefToTypeScript(callbackReturnType); - - // Callbacks are always async in TypeScript - return $"({paramsString}) => Promise<{returnType}>"; - } - private void GenerateCallbackRegistration(AtsParameterInfo callbackParam, string indent = " ", string clientExpression = "this._client") { var callbackParameters = callbackParam.CallbackParameters; @@ -3050,27 +2094,27 @@ private void GenerateCallbackBody(AtsParameterInfo callbackParam, IReadOnlyList< private void GenerateCallbackParameterConversion(AtsCallbackParameterInfo callbackParameter, string callbackArgName, string clientExpression, string indent) { - var tsType = MapTypeRefToTypeScript(callbackParameter.Type); + var tsType = _projector.MapTypeRefToTypeScript(callbackParameter.Type); var cbTypeId = callbackParameter.Type.TypeId; if (cbTypeId == AtsConstants.CancellationToken) { WriteLine($"{indent}const {callbackParameter.Name} = CancellationToken.fromValue({callbackArgName});"); } - else if (IsDictionaryType(callbackParameter.Type) && !callbackParameter.Type.IsReadOnly) + else if (TypeScriptApiProjector.IsDictionaryType(callbackParameter.Type) && !callbackParameter.Type.IsReadOnly) { - var keyType = MapTypeRefToTypeScript(callbackParameter.Type.KeyType); - var valueType = MapTypeRefToTypeScript(callbackParameter.Type.ValueType); - var handleType = GetHandleTypeName(cbTypeId); + var keyType = _projector.MapTypeRefToTypeScript(callbackParameter.Type.KeyType); + var valueType = _projector.MapTypeRefToTypeScript(callbackParameter.Type.ValueType); + var handleType = TypeScriptApiProjector.GetHandleTypeName(cbTypeId); WriteLine($"{indent}const {callbackParameter.Name}Handle = wrapIfHandle({callbackArgName}) as {handleType};"); WriteLine($"{indent}const {callbackParameter.Name} = new AspireDict<{keyType}, {valueType}>({callbackParameter.Name}Handle, {clientExpression}, '{cbTypeId}');"); } - else if (_wrapperClassNames.TryGetValue(cbTypeId, out var wrapperClassName)) + else if (_projector.WrapperClassNames.TryGetValue(cbTypeId, out var wrapperClassName)) { - var handleType = GetHandleTypeName(cbTypeId); + var handleType = TypeScriptApiProjector.GetHandleTypeName(cbTypeId); WriteLine($"{indent}const {callbackParameter.Name}Handle = wrapIfHandle({callbackArgName}) as {handleType};"); - WriteLine($"{indent}const {callbackParameter.Name} = new {GetImplementationClassName(wrapperClassName)}({callbackParameter.Name}Handle, {clientExpression});"); + WriteLine($"{indent}const {callbackParameter.Name} = new {TypeScriptApiProjector.GetImplementationClassName(wrapperClassName)}({callbackParameter.Name}Handle, {clientExpression});"); } else { @@ -3080,7 +2124,7 @@ private void GenerateCallbackParameterConversion(AtsCallbackParameterInfo callba private void GenerateConnectionHelper() { - var builderHandle = GetHandleTypeName(AtsConstants.BuilderTypeId); + var builderHandle = TypeScriptApiProjector.GetHandleTypeName(AtsConstants.BuilderTypeId); WriteLine($$""" // ============================================================================ @@ -3231,17 +2275,17 @@ private void GenerateHandleWrapperRegistrations(List typeClasses, // Register type classes (context types like EnvironmentCallbackContext) foreach (var typeClass in typeClasses) { - var className = _wrapperClassNames.GetValueOrDefault(typeClass.TypeId) ?? DeriveClassName(typeClass.TypeId); - var handleType = GetHandleTypeName(typeClass.TypeId); - WriteLine($"registerHandleWrapper('{typeClass.TypeId}', (handle, client) => new {GetImplementationClassName(className)}(handle as {handleType}, client));"); + var className = _projector.WrapperClassNames.GetValueOrDefault(typeClass.TypeId) ?? TypeScriptApiProjector.DeriveClassName(typeClass.TypeId); + var handleType = TypeScriptApiProjector.GetHandleTypeName(typeClass.TypeId); + WriteLine($"registerHandleWrapper('{typeClass.TypeId}', (handle, client) => new {TypeScriptApiProjector.GetImplementationClassName(className)}(handle as {handleType}, client));"); } // Register resource builder classes foreach (var builder in resourceBuilders) { - var className = _wrapperClassNames.GetValueOrDefault(builder.TypeId) ?? DeriveClassName(builder.TypeId); - var handleType = GetHandleTypeName(builder.TypeId); - WriteLine($"registerHandleWrapper('{builder.TypeId}', (handle, client) => new {GetImplementationClassName(className)}(handle as {handleType}, client));"); + var className = _projector.WrapperClassNames.GetValueOrDefault(builder.TypeId) ?? TypeScriptApiProjector.DeriveClassName(builder.TypeId); + var handleType = TypeScriptApiProjector.GetHandleTypeName(builder.TypeId); + WriteLine($"registerHandleWrapper('{builder.TypeId}', (handle, client) => new {TypeScriptApiProjector.GetImplementationClassName(className)}(handle as {handleType}, client));"); } WriteLine(); @@ -3254,9 +2298,9 @@ private void GenerateHandleWrapperRegistrations(List typeClasses, /// private void GenerateTypeClass(BuilderModel model) { - var handleType = GetHandleTypeName(model.TypeId); - var className = DeriveClassName(model.TypeId); - var implementationClassName = GetImplementationClassName(className); + var handleType = TypeScriptApiProjector.GetHandleTypeName(model.TypeId); + var className = TypeScriptApiProjector.DeriveClassName(model.TypeId); + var implementationClassName = TypeScriptApiProjector.GetImplementationClassName(className); GenerateTypeClassInterface(model); @@ -3282,9 +2326,9 @@ private void GenerateTypeClass(BuilderModel model) WriteLine(); // Group getters and setters by property name to create property members - var properties = GroupPropertiesByName(getters, setters); + var properties = TypeScriptApiProjector.GroupPropertiesByName(getters, setters); var getterOnlyProperties = properties - .Where(p => IsGetterOnlyProperty(p.Getter, p.Setter)) + .Where(p => TypeScriptApiProjector.IsGetterOnlyProperty(p.Getter, p.Setter)) .ToList(); // Generate property access members @@ -3324,64 +2368,6 @@ private void GenerateTypeClass(BuilderModel model) } } - /// - /// Groups getters and setters by property name. - /// - private static List<(string PropertyName, AtsCapabilityInfo? Getter, AtsCapabilityInfo? Setter)> GroupPropertiesByName( - List getters, List setters) - { - var result = new List<(string PropertyName, AtsCapabilityInfo? Getter, AtsCapabilityInfo? Setter)>(); - var processedNames = new HashSet(); - - // Process getters - foreach (var getter in getters) - { - var propName = ExtractPropertyName(getter.MethodName); - if (processedNames.Contains(propName)) - { - continue; - } - processedNames.Add(propName); - - // Find matching setter (setPropertyName for propertyName) - var setterName = "set" + char.ToUpperInvariant(propName[0]) + propName[1..]; - var setter = setters.FirstOrDefault(s => ExtractPropertyName(s.MethodName).Equals(setterName, StringComparison.OrdinalIgnoreCase)); - - result.Add((propName, getter, setter)); - } - - // Process any setters without matching getters - foreach (var setter in setters) - { - var setterMethodName = ExtractPropertyName(setter.MethodName); - // setPropertyName -> propertyName - if (setterMethodName.StartsWith("set", StringComparison.OrdinalIgnoreCase) && setterMethodName.Length > 3) - { - var propName = char.ToLowerInvariant(setterMethodName[3]) + setterMethodName[4..]; - if (!processedNames.Contains(propName)) - { - processedNames.Add(propName); - result.Add((propName, null, setter)); - } - } - } - - return result; - } - - /// - /// Extracts the property name from a method name like "ClassName.propertyName" or "setPropertyName". - /// - private static string ExtractPropertyName(string methodName) - { - // Handle "ClassName.propertyName" format - if (methodName.Contains('.')) - { - return methodName[(methodName.LastIndexOf('.') + 1)..]; - } - return methodName; - } - /// /// Generates a property access member. /// @@ -3407,7 +2393,7 @@ private static string ExtractPropertyName(string methodName) /// private void GeneratePropertyLikeObject(string propertyName, AtsCapabilityInfo? getter, AtsCapabilityInfo? setter) { - if (IsGetterOnlyProperty(getter, setter)) + if (TypeScriptApiProjector.IsGetterOnlyProperty(getter, setter)) { GenerateGetterOnlyPropertyMethod(propertyName, getter!); return; @@ -3418,25 +2404,25 @@ private void GeneratePropertyLikeObject(string propertyName, AtsCapabilityInfo? if (getter != null) { - returnType = MapTypeRefToTypeScript(getter.ReturnType); + returnType = _projector.MapTypeRefToTypeScript(getter.ReturnType); // Mutable dictionary/list properties stay as property accessors so callers can use // wrapper operations (for example, property.get()/set() or list/dict helpers) // without switching to the getter-only method shape. - if (IsDictionaryType(getter.ReturnType)) + if (TypeScriptApiProjector.IsDictionaryType(getter.ReturnType)) { GenerateMutableDictionaryProperty(propertyName, getter); return; } - if (IsListType(getter.ReturnType)) + if (TypeScriptApiProjector.IsListType(getter.ReturnType)) { GenerateMutableListProperty(propertyName, getter); return; } // Check if return type is a wrapper class - use property-like object returning wrapper - if (getter.ReturnType?.TypeId != null && _wrapperClassNames.TryGetValue(getter.ReturnType.TypeId, out var wrapperClassName)) + if (getter.ReturnType?.TypeId != null && _projector.WrapperClassNames.TryGetValue(getter.ReturnType.TypeId, out var wrapperClassName)) { GenerateWrapperPropertyObject(propertyName, getter, setter, wrapperClassName); return; @@ -3474,7 +2460,7 @@ private void GeneratePropertyLikeObject(string propertyName, AtsCapabilityInfo? var valueParam = setter.Parameters.FirstOrDefault(p => p.Name == "value"); if (valueParam != null) { - var valueType = MapInputTypeToTypeScript(valueParam.Type); + var valueType = _projector.MapInputTypeToTypeScript(valueParam.Type); WriteLine($" set: async (value: {valueType}): Promise => {{"); GeneratePromiseResolutionForParam("value", valueParam.Type, " "); WriteLine($" await this._client.invokeCapability("); @@ -3491,19 +2477,19 @@ private void GeneratePropertyLikeObject(string propertyName, AtsCapabilityInfo? private void GenerateGetterOnlyPropertyMethod(string propertyName, AtsCapabilityInfo getter) { - if (IsDictionaryType(getter.ReturnType)) + if (TypeScriptApiProjector.IsDictionaryType(getter.ReturnType)) { GenerateDictionaryProperty(propertyName, getter); return; } - if (IsListType(getter.ReturnType)) + if (TypeScriptApiProjector.IsListType(getter.ReturnType)) { GenerateListProperty(propertyName, getter); return; } - if (getter.ReturnType?.TypeId != null && _wrapperClassNames.TryGetValue(getter.ReturnType.TypeId, out var wrapperClassName)) + if (getter.ReturnType?.TypeId != null && _projector.WrapperClassNames.TryGetValue(getter.ReturnType.TypeId, out var wrapperClassName)) { GenerateWrapperGetterOnlyPropertyMethod(propertyName, getter, wrapperClassName); return; @@ -3514,9 +2500,9 @@ private void GenerateGetterOnlyPropertyMethod(string propertyName, AtsCapability // promise in their hand-written ...Promise thenable so by-name accessors chain without an // intermediate await. Awaiting the wrapper still resolves to the plain collection, preserving // the existing `await (await x.inputs()).value(...)` form. - if (TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out var promiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out var promiseImplementationClassName)) { - var collectionType = GetGetterOnlyPropertyReturnType(getter.ReturnType); + var collectionType = _projector.GetGetterOnlyPropertyReturnType(getter.ReturnType); WriteLine($" {propertyName}(): {promiseInterfaceName} {{"); WriteLine($" return new {promiseImplementationClassName}(this._client.invokeCapability<{collectionType}>("); WriteLine($" '{getter.CapabilityId}',"); @@ -3527,7 +2513,7 @@ private void GenerateGetterOnlyPropertyMethod(string propertyName, AtsCapability return; } - var returnType = GetGetterOnlyPropertyReturnType(getter.ReturnType); + var returnType = _projector.GetGetterOnlyPropertyReturnType(getter.ReturnType); WriteLine($" async {propertyName}(): Promise<{returnType}> {{"); if (getter.ReturnType?.TypeId == AtsConstants.CancellationToken) @@ -3551,10 +2537,10 @@ private void GenerateGetterOnlyPropertyMethod(string propertyName, AtsCapability private void GenerateWrapperGetterOnlyPropertyMethod(string propertyName, AtsCapabilityInfo getter, string wrapperClassName) { - var handleType = GetHandleTypeName(getter.ReturnType!.TypeId); - var wrapperImplementationClassName = GetImplementationClassName(wrapperClassName); + var handleType = TypeScriptApiProjector.GetHandleTypeName(getter.ReturnType!.TypeId); + var wrapperImplementationClassName = TypeScriptApiProjector.GetImplementationClassName(wrapperClassName); - if (TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out var promiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out var promiseImplementationClassName)) { WriteLine($" {propertyName}(): {promiseInterfaceName} {{"); WriteLine(" const promise = (async () => {"); @@ -3605,11 +2591,11 @@ private void GenerateWrapperGetterOnlyPropertyMethod(string propertyName, AtsCap /// private void GenerateWrapperPropertyObject(string propertyName, AtsCapabilityInfo getter, AtsCapabilityInfo? setter, string wrapperClassName) { - var handleType = GetHandleTypeName(getter.ReturnType!.TypeId); - var wrapperImplementationClassName = GetImplementationClassName(wrapperClassName); + var handleType = TypeScriptApiProjector.GetHandleTypeName(getter.ReturnType!.TypeId); + var wrapperImplementationClassName = TypeScriptApiProjector.GetImplementationClassName(wrapperClassName); WriteLine($" {propertyName} = {{"); - if (TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out var promiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out var promiseImplementationClassName)) { WriteLine($" get: (): {promiseInterfaceName} => {{"); WriteLine(" const promise = (async () => {"); @@ -3638,7 +2624,7 @@ private void GenerateWrapperPropertyObject(string propertyName, AtsCapabilityInf var valueParam = setter.Parameters.FirstOrDefault(p => p.Name == "value"); if (valueParam != null) { - var valueType = MapInputTypeToTypeScript(valueParam.Type); + var valueType = _projector.MapInputTypeToTypeScript(valueParam.Type); WriteLine($" set: async (value: {valueType}): Promise => {{"); GeneratePromiseResolutionForParam("value", valueParam.Type, " "); WriteLine($" await this._client.invokeCapability("); @@ -3653,22 +2639,6 @@ private void GenerateWrapperPropertyObject(string propertyName, AtsCapabilityInf WriteLine(); } - /// - /// Checks if a type reference is a dictionary type. - /// - private static bool IsDictionaryType(AtsTypeRef? typeRef) - { - return typeRef?.Category == AtsTypeCategory.Dict; - } - - /// - /// Checks if a type reference is a list type. - /// - private static bool IsListType(AtsTypeRef? typeRef) - { - return typeRef?.Category == AtsTypeCategory.List; - } - /// /// Generates a getter-only method for dictionary types. /// @@ -3681,12 +2651,12 @@ private void GenerateDictionaryProperty(string propertyName, AtsCapabilityInfo g // Try to extract key and value types from Dict type if (getter.ReturnType?.KeyType != null) { - keyType = MapTypeRefToTypeScript(getter.ReturnType.KeyType); + keyType = _projector.MapTypeRefToTypeScript(getter.ReturnType.KeyType); } if (getter.ReturnType?.ValueType != null) { // Union types will be mapped correctly via MapTypeRefToTypeScript - valueType = MapTypeRefToTypeScript(getter.ReturnType.ValueType); + valueType = _projector.MapTypeRefToTypeScript(getter.ReturnType.ValueType); } var typeId = $"'{getter.CapabilityId}'"; @@ -3715,12 +2685,12 @@ private void GenerateMutableDictionaryProperty(string propertyName, AtsCapabilit if (getter.ReturnType?.KeyType != null) { - keyType = MapTypeRefToTypeScript(getter.ReturnType.KeyType); + keyType = _projector.MapTypeRefToTypeScript(getter.ReturnType.KeyType); } if (getter.ReturnType?.ValueType != null) { - valueType = MapTypeRefToTypeScript(getter.ReturnType.ValueType); + valueType = _projector.MapTypeRefToTypeScript(getter.ReturnType.ValueType); } var typeId = $"'{getter.CapabilityId}'"; @@ -3751,7 +2721,7 @@ private void GenerateListProperty(string propertyName, AtsCapabilityInfo getter) if (getter.ReturnType?.ElementType != null) { - elementType = MapTypeRefToTypeScript(getter.ReturnType.ElementType); + elementType = _projector.MapTypeRefToTypeScript(getter.ReturnType.ElementType); } var typeId = $"'{getter.CapabilityId}'"; @@ -3779,7 +2749,7 @@ private void GenerateMutableListProperty(string propertyName, AtsCapabilityInfo if (getter.ReturnType?.ElementType != null) { - elementType = MapTypeRefToTypeScript(getter.ReturnType.ElementType); + elementType = _projector.MapTypeRefToTypeScript(getter.ReturnType.ElementType); } var typeId = $"'{getter.CapabilityId}'"; @@ -3828,26 +2798,26 @@ private void GenerateContextMethod(AtsCapabilityInfo method) var userParams = method.Parameters.Where(p => p.Name != targetParamName).ToList(); // Separate required and optional parameters - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(method); - var publicOptionsParamName = GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(method); + var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list using options pattern - var paramsString = BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, GetTrailingCancellationTokenParameter(optionalParams)); + var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); // Determine return type var returnType = GetReturnTypeId(method) != null - ? MapTypeRefToTypeScript(method.ReturnType) + ? _projector.MapTypeRefToTypeScript(method.ReturnType) : "void"; - if (TryGetPromiseWrapperType(method.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(method.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) { var returnTypeId = method.ReturnType!.TypeId; - var returnClassName = GetConcreteClassName(returnTypeId); - var returnImplementationClassName = GetImplementationClassName(returnClassName); - var returnHandleType = GetHandleTypeName(returnTypeId); + var returnClassName = _projector.GetConcreteClassName(returnTypeId); + var returnImplementationClassName = TypeScriptApiProjector.GetImplementationClassName(returnClassName); + var returnHandleType = TypeScriptApiProjector.GetHandleTypeName(returnTypeId); WriteCapabilityDocComment(" ", method, requiredParams, hasOptionals ? publicOptionsParamName : null); Write($" {methodName}("); @@ -3858,7 +2828,7 @@ private void GenerateContextMethod(AtsCapabilityInfo method) foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } GenerateResolveAndBuildArgs(targetParamName, userParams, requiredParams, optionalParams, useSafeOptionalLocalNames: true, indent: " "); @@ -3885,7 +2855,7 @@ private void GenerateContextMethod(AtsCapabilityInfo method) foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } // Resolve promise-like params and build args @@ -3934,7 +2904,7 @@ private void GenerateContextMethod(AtsCapabilityInfo method) /// private void GenerateWrapperMethod(AtsCapabilityInfo capability) { - var methodName = GetTypeScriptMethodName(capability.MethodName); + var methodName = TypeScriptApiProjector.GetTypeScriptMethodName(capability.MethodName); // First arg is the handle (implicit via this._handle) - use metadata instead of string parsing var firstParamName = capability.TargetParameterName ?? "builder"; @@ -3943,24 +2913,24 @@ private void GenerateWrapperMethod(AtsCapabilityInfo capability) var userParams = capability.Parameters.Where(p => p.Name != firstParamName).ToList(); // Separate required and optional parameters - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var publicOptionsParamName = GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list using options pattern - var paramsString = BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, GetTrailingCancellationTokenParameter(optionalParams)); + var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); // Determine return type - var returnType = MapTypeRefToTypeScript(capability.ReturnType); + var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); - if (TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) { var returnTypeId = capability.ReturnType!.TypeId; - var returnClassName = GetConcreteClassName(returnTypeId); - var returnImplementationClassName = GetImplementationClassName(returnClassName); - var returnHandleType = GetHandleTypeName(returnTypeId); + var returnClassName = _projector.GetConcreteClassName(returnTypeId); + var returnImplementationClassName = TypeScriptApiProjector.GetImplementationClassName(returnClassName); + var returnHandleType = TypeScriptApiProjector.GetHandleTypeName(returnTypeId); WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? publicOptionsParamName : null); Write($" {methodName}("); @@ -3971,7 +2941,7 @@ private void GenerateWrapperMethod(AtsCapabilityInfo capability) foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } GenerateResolveAndBuildArgs(firstParamName, userParams, requiredParams, optionalParams, useSafeOptionalLocalNames: true, indent: " "); @@ -3998,7 +2968,7 @@ private void GenerateWrapperMethod(AtsCapabilityInfo capability) foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } // Resolve promise-like params and build args @@ -4045,14 +3015,14 @@ private void GenerateWrapperMethod(AtsCapabilityInfo capability) /// private void GenerateTypeClassMethod(BuilderModel model, AtsCapabilityInfo capability) { - var className = DeriveClassName(model.TypeId); + var className = TypeScriptApiProjector.DeriveClassName(model.TypeId); var promiseClass = $"{className}Promise"; - var promiseImplementationClass = GetImplementationPromiseClassName(className); + var promiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(className); // Use OwningTypeName if available to extract method name, otherwise parse from MethodName var methodName = !string.IsNullOrEmpty(capability.OwningTypeName) && capability.MethodName.Contains('.') ? capability.MethodName[(capability.MethodName.LastIndexOf('.') + 1)..] - : GetTypeScriptMethodName(capability.MethodName); + : TypeScriptApiProjector.GetTypeScriptMethodName(capability.MethodName); var internalMethodName = $"_{methodName}Internal"; @@ -4061,38 +3031,38 @@ private void GenerateTypeClassMethod(BuilderModel model, AtsCapabilityInfo capab var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); // Separate required and optional parameters - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var publicOptionsParamName = GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list for public method - var publicParamsString = BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, GetTrailingCancellationTokenParameter(optionalParams)); + var publicParamsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); // Build parameter list for internal method (all params positional) var internalParamDefs = new List(); foreach (var param in userParams) { - var tsType = MapParameterToTypeScript(param); + var tsType = _projector.MapParameterToTypeScript(param); var optional = param.IsOptional || param.IsNullable ? "?" : ""; internalParamDefs.Add($"{param.Name}{optional}: {tsType}"); } var internalParamsString = string.Join(", ", internalParamDefs); // Check if return type has a Promise wrapper - var returnPromiseWrapper = GetPromiseWrapperForReturnType(capability.ReturnType); - var returnType = MapTypeRefToTypeScript(capability.ReturnType); + var returnPromiseWrapper = _projector.GetPromiseWrapperForReturnType(capability.ReturnType); + var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); var isVoid = capability.ReturnType == null || capability.ReturnType.TypeId == AtsConstants.Void; // If return type has a Promise wrapper, generate internal + fluent pattern if (returnPromiseWrapper != null) { - var returnWrapperClass = _wrapperClassNames.GetValueOrDefault(capability.ReturnType!.TypeId) - ?? DeriveClassName(capability.ReturnType.TypeId); - var returnWrapperImplementationClass = GetImplementationClassName(returnWrapperClass); - var returnPromiseImplementationClass = GetImplementationPromiseClassName(returnWrapperClass); - var returnHandleType = GetHandleTypeName(capability.ReturnType.TypeId); + var returnWrapperClass = _projector.WrapperClassNames.GetValueOrDefault(capability.ReturnType!.TypeId) + ?? TypeScriptApiProjector.DeriveClassName(capability.ReturnType.TypeId); + var returnWrapperImplementationClass = TypeScriptApiProjector.GetImplementationClassName(returnWrapperClass); + var returnPromiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(returnWrapperClass); + var returnHandleType = TypeScriptApiProjector.GetHandleTypeName(capability.ReturnType.TypeId); // Generate internal async method WriteLine($" /** @internal */"); @@ -4131,7 +3101,7 @@ private void GenerateTypeClassMethod(BuilderModel model, AtsCapabilityInfo capab foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } var internalCallArgs = userParams.Select(p => optionalParams.Contains(p) ? GetLocalParameterName(p) : p.Name); @@ -4189,7 +3159,7 @@ private void GenerateTypeClassMethod(BuilderModel model, AtsCapabilityInfo capab foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } Write($" return new {promiseImplementationClass}(this.{internalMethodName}("); @@ -4209,7 +3179,7 @@ private void GenerateTypeClassMethod(BuilderModel model, AtsCapabilityInfo capab foreach (var param in hasDirectOptionsParameter ? [] : optionalParams) { var localParameterName = GetLocalParameterName(param); - WriteLine($" {(IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); + WriteLine($" {(_projector.IsWidenedHandleType(param.Type) ? "let" : "const")} {localParameterName} = {publicOptionsParamName}?.{param.Name};"); } // Handle callback registration if any @@ -4269,9 +3239,9 @@ private void GenerateTypeClassMethod(BuilderModel model, AtsCapabilityInfo capab /// private void GenerateTypeClassThenableWrapper(BuilderModel model, List methods) { - var className = DeriveClassName(model.TypeId); + var className = TypeScriptApiProjector.DeriveClassName(model.TypeId); var promiseClass = $"{className}Promise"; - var promiseImplementationClass = GetImplementationPromiseClassName(className); + var promiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(className); WriteLine($"/**"); WriteLine($" * Thenable wrapper for {className} that enables fluent chaining."); @@ -4293,15 +3263,15 @@ private void GenerateTypeClassThenableWrapper(BuilderModel model, List c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); var setters = model.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); - var getterOnlyProperties = GroupPropertiesByName(getters, setters) - .Where(p => IsGetterOnlyProperty(p.Getter, p.Setter)) + var getterOnlyProperties = TypeScriptApiProjector.GroupPropertiesByName(getters, setters) + .Where(p => TypeScriptApiProjector.IsGetterOnlyProperty(p.Getter, p.Setter)) .ToList(); foreach (var prop in getterOnlyProperties) { - var returnType = GetGetterOnlyPropertyMethodReturnType(prop.Getter!.ReturnType); + var returnType = _projector.GetGetterOnlyPropertyMethodReturnType(prop.Getter!.ReturnType); WriteLine($" {prop.PropertyName}(): {returnType} {{"); - if (TryGetPromiseWrapperType(prop.Getter!.ReturnType, out _, out var propertyPromiseImplementationClassName)) + if (_projector.TryGetPromiseWrapperType(prop.Getter!.ReturnType, out _, out var propertyPromiseImplementationClassName)) { WriteLine($" return new {propertyPromiseImplementationClassName}(this._promise.then(obj => obj.{prop.PropertyName}()), this._client, false);"); } @@ -4318,23 +3288,23 @@ private void GenerateTypeClassThenableWrapper(BuilderModel model, List p.Name != targetParamName).ToList(); // Separate required and optional parameters - var (requiredParams, optionalParams) = SeparateParameters(userParams); + var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var trailingCancellationToken = GetTrailingCancellationTokenParameter(optionalParams); + var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); + var trailingCancellationToken = TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams); // Build parameter list using options pattern var publicParamDefs = new List(); foreach (var param in requiredParams) { - var tsType = MapParameterToTypeScript(param); + var tsType = _projector.MapParameterToTypeScript(param); publicParamDefs.Add($"{param.Name}: {tsType}"); } if (hasOptionals) @@ -4343,7 +3313,7 @@ private void GenerateTypeClassThenableWrapper(BuilderModel model, List - /// Groups capabilities by ExpandedTargetTypes to create builder models. - /// Uses expansion to map interface targets to their concrete implementations. - /// Also creates builders for interface types (for use as return type wrappers). - /// - private static List CreateBuilderModels(IReadOnlyList capabilities) - { - // Group capabilities by expanded target type IDs - // A capability targeting IResource with ExpandedTargetTypes = [RedisResource] - // will be assigned to Aspire.Hosting.Redis/RedisResource (the concrete type) - var capabilitiesByTypeId = new Dictionary>(); - - // Track the AtsTypeRef for each typeId (from ExpandedTargetTypes or TargetType metadata) - var typeRefsByTypeId = new Dictionary(); - - // Also track interface types and their capabilities (for interface wrapper classes) - var interfaceCapabilities = new Dictionary>(); - - foreach (var cap in capabilities) - { - var targetTypeRef = cap.TargetType; - var targetTypeId = cap.TargetTypeId; - if (targetTypeRef == null || string.IsNullOrEmpty(targetTypeId)) - { - // Entry point methods - handled separately - continue; - } - - // Use category-based check instead of string parsing - if (targetTypeRef.Category != AtsTypeCategory.Handle) - { - continue; - } - - // These types are implemented manually in base.mts, including handle wrapper - // registrations, so they must not also generate duplicate wrappers in aspire.mts. - if (targetTypeId is AtsConstants.ReferenceExpressionTypeId or InteractionInputCollectionTypeId) - { - continue; - } - - // Use expanded types if available, otherwise fall back to the original target - var expandedTypes = cap.ExpandedTargetTypes; - if (expandedTypes is { Count: > 0 }) - { - // Flatten to concrete types - foreach (var expandedType in expandedTypes) - { - if (!capabilitiesByTypeId.TryGetValue(expandedType.TypeId, out var list)) - { - list = []; - capabilitiesByTypeId[expandedType.TypeId] = list; - // Store the type ref for this expanded type - typeRefsByTypeId[expandedType.TypeId] = expandedType; - } - list.Add(cap); - } - - // Also track the original interface type for wrapper class generation - if (targetTypeRef.IsInterface) - { - if (!interfaceCapabilities.TryGetValue(targetTypeId, out var interfaceList)) - { - interfaceList = []; - interfaceCapabilities[targetTypeId] = interfaceList; - // Store the type ref for the interface - typeRefsByTypeId[targetTypeId] = targetTypeRef; - } - interfaceList.Add(cap); - } - } - else - { - // No expansion - use original target (concrete type) - if (!capabilitiesByTypeId.TryGetValue(targetTypeId, out var list)) - { - list = []; - capabilitiesByTypeId[targetTypeId] = list; - // Store the type ref for this target type - typeRefsByTypeId[targetTypeId] = targetTypeRef; - } - list.Add(cap); - } - } - - // Create a builder for each concrete type with its specific capabilities - var builders = new List(); - foreach (var (typeId, typeCapabilities) in capabilitiesByTypeId) - { - var builderClassName = DeriveClassName(typeId); - - // Get the type ref from tracked metadata (based on target type, not return type) - var typeRef = typeRefsByTypeId.GetValueOrDefault(typeId); - - // Deduplicate capabilities by CapabilityId to avoid duplicate methods - var uniqueCapabilities = typeCapabilities - .GroupBy(c => c.CapabilityId) - .Select(g => g.First()) - .ToList(); - - var builder = new BuilderModel - { - TypeId = typeId, - BuilderClassName = builderClassName, - Capabilities = uniqueCapabilities, - IsInterface = typeRef?.IsInterface ?? false, - TargetType = typeRef - }; - - builders.Add(builder); - } - - // Also create builders for interface types (for use as return type wrappers) - // These are needed when methods return interface types like IResourceWithConnectionString - foreach (var (interfaceTypeId, caps) in interfaceCapabilities) - { - // Skip if already added (shouldn't happen, but be safe) - if (capabilitiesByTypeId.ContainsKey(interfaceTypeId)) - { - continue; - } - - var builderClassName = DeriveClassName(interfaceTypeId); - - // Get the type ref from tracked metadata - var typeRef = typeRefsByTypeId.GetValueOrDefault(interfaceTypeId); - - // Deduplicate capabilities - var uniqueCapabilities = caps - .GroupBy(c => c.CapabilityId) - .Select(g => g.First()) - .ToList(); - - var builder = new BuilderModel - { - TypeId = interfaceTypeId, - BuilderClassName = builderClassName, - Capabilities = uniqueCapabilities, - IsInterface = true, - TargetType = typeRef - }; - - builders.Add(builder); - } - - // Also create builders for resource types referenced anywhere in capabilities - // This handles types like RedisCommanderResource that appear in callback signatures, - // return types, or parameter types but aren't capability targets - var allReferencedTypeRefs = CollectAllReferencedTypes(capabilities); - - // Track all types we already have builders for (concrete + interface) - var existingBuilderTypeIds = new HashSet(capabilitiesByTypeId.Keys); - foreach (var (interfaceTypeId, _) in interfaceCapabilities) - { - existingBuilderTypeIds.Add(interfaceTypeId); - } - - foreach (var (typeId, typeRef) in allReferencedTypeRefs) - { - // Skip types we already have builders for (from concrete or interface lists) - if (existingBuilderTypeIds.Contains(typeId)) - { - continue; - } - - // Only create builders for resource types (using metadata instead of string parsing) - if (!typeRef.IsResourceBuilder) - { - continue; - } - - var builderClassName = DeriveClassName(typeId); - var builder = new BuilderModel - { - TypeId = typeId, - BuilderClassName = builderClassName, - Capabilities = [], // No specific capabilities - uses base type methods - IsInterface = typeRef.IsInterface, - TargetType = typeRef - }; - builders.Add(builder); - } - - // Deduplicate builders by class name, preferring concrete types over interfaces. - // This handles cases where both a concrete type (e.g. AzureKeyVaultResource) and - // its interface (IAzureKeyVaultResource → AzureKeyVaultResource) produce the same class name. - // Sort: concrete types first, then interfaces - return builders - .OrderBy(b => b.IsInterface) - .ThenBy(b => b.BuilderClassName) - .GroupBy(b => b.BuilderClassName) - .Select(g => g.First()) - .ToList(); - } - - /// - /// Collects all type refs referenced in capabilities (return types, parameter types, callback types, etc.) - /// Returns a dictionary mapping typeId to AtsTypeRef for use in builder creation. - /// - private static Dictionary CollectAllReferencedTypes(IReadOnlyList capabilities) - { - var typeRefs = new Dictionary(); - - void CollectFromTypeRef(AtsTypeRef? typeRef) - { - if (typeRef == null) - { - return; - } - - if (!string.IsNullOrEmpty(typeRef.TypeId) && typeRef.Category == AtsTypeCategory.Handle) - { - typeRefs.TryAdd(typeRef.TypeId, typeRef); - } - - // Also check nested types (generics, arrays, etc.) - CollectFromTypeRef(typeRef.ElementType); - CollectFromTypeRef(typeRef.KeyType); - CollectFromTypeRef(typeRef.ValueType); - if (typeRef.UnionTypes != null) - { - foreach (var unionType in typeRef.UnionTypes) - { - CollectFromTypeRef(unionType); - } - } - } - - foreach (var cap in capabilities) - { - // Check return type - CollectFromTypeRef(cap.ReturnType); - - // Check parameter types - foreach (var param in cap.Parameters) - { - CollectFromTypeRef(param.Type); - - // Check callback parameter types and return type - if (param.IsCallback) - { - if (param.CallbackParameters != null) - { - foreach (var cbParam in param.CallbackParameters) - { - CollectFromTypeRef(cbParam.Type); - } - } - CollectFromTypeRef(param.CallbackReturnType); - } - } - } - - return typeRefs; - } - - /// - /// Gets entry point capabilities (those without TargetTypeId). - /// - private static List GetEntryPointCapabilities(IReadOnlyList capabilities) - { - return capabilities.Where(c => string.IsNullOrEmpty(c.TargetTypeId)).ToList(); - } - - /// - /// Derives the class name from an ATS type ID. - /// For interfaces like IResource, strips the leading 'I'. - /// - private static string DeriveClassName(string typeId) - { - var typeName = ExtractSimpleTypeName(typeId); - - // Strip leading 'I' from interface types - if (typeName.StartsWith('I') && typeName.Length > 1 && char.IsUpper(typeName[1])) - { - return typeName[1..]; - } - - return typeName; - } - - /// - /// Gets the handle type alias name for a type ID. - /// - private static string GetHandleTypeName(string typeId) - { - var typeName = ExtractSimpleTypeName(typeId); - - // Sanitize generic types like "Dict" -> "DictStringObject" - // and array types like "string[]" -> "stringArray" - typeName = typeName - .Replace("[]", "Array", StringComparison.Ordinal) - .Replace("<", "", StringComparison.Ordinal) - .Replace(">", "", StringComparison.Ordinal) - .Replace(",", "", StringComparison.Ordinal); - - return $"{typeName}Handle"; - } - - /// - /// Extracts the simple type name from a type ID. - /// - /// - /// "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource" → "IResource" - /// "Aspire.Hosting/Aspire.Hosting.DistributedApplication" → "DistributedApplication" - /// - private static string ExtractSimpleTypeName(string typeId) - { - var slashIndex = typeId.LastIndexOf('/'); - var fullTypeName = slashIndex >= 0 ? typeId[(slashIndex + 1)..] : typeId; - - var dotIndex = fullTypeName.LastIndexOf('.'); - return dotIndex >= 0 ? fullTypeName[(dotIndex + 1)..] : fullTypeName; - } - - /// - /// Determines if a type has generated async members and should have a Promise wrapper. - /// Types with instance methods, wrapper methods, or getter-only properties get Promise wrappers. - /// - private static bool HasChainableMethods(BuilderModel model) - { - var hasMethods = model.Capabilities.Any(c => - c.CapabilityKind == AtsCapabilityKind.InstanceMethod || - c.CapabilityKind == AtsCapabilityKind.Method); - if (hasMethods) - { - return true; - } - - var getters = model.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); - var setters = model.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); - - return GroupPropertiesByName(getters, setters).Any(p => IsGetterOnlyProperty(p.Getter, p.Setter)); - } - - /// - /// Gets the Promise wrapper class name for a return type, if one exists. - /// Returns null if the return type doesn't have a Promise wrapper. - /// - private string? GetPromiseWrapperForReturnType(AtsTypeRef? returnType) - { - if (returnType == null) - { - return null; - } - - // Check if the return type has a Promise wrapper - if (_typesWithPromiseWrappers.Contains(returnType.TypeId)) - { - var className = _wrapperClassNames.GetValueOrDefault(returnType.TypeId) - ?? DeriveClassName(returnType.TypeId); - return $"{className}Promise"; - } - - return null; - } } diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs new file mode 100644 index 00000000000..c2527ca29cd --- /dev/null +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs @@ -0,0 +1,188 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace Aspire.Hosting.CodeGeneration.TypeScript; + +/// +/// Serializes a into the canonical schema version 1 export document. +/// +/// +/// The document is written by hand rather than through reflection-based serialization because the +/// shape is a published contract that documentation sites bind to. Writing it explicitly makes the +/// contract reviewable in one place, keeps property order stable so exports diff cleanly between SDK +/// versions, and drops empty collections and null strings so a version bump only shows real API +/// changes. +/// +internal static class TypeScriptApiExportWriter +{ + /// The schema version emitted by this writer. + public const int SchemaVersion = TypeScriptApiProjector.ExportSchemaVersion; + + public static JsonObject Write(TypeScriptApiModel model) + { + ArgumentNullException.ThrowIfNull(model); + + var modules = new JsonArray(); + foreach (var module in model.Modules) + { + modules.Add((JsonNode)WriteModule(module)); + } + + var declarations = new JsonArray(); + foreach (var declaration in model.Declarations) + { + declarations.Add((JsonNode)new JsonObject + { + ["id"] = declaration.Id, + ["owningAssembly"] = declaration.OwningAssemblyName, + ["content"] = declaration.Content + }); + } + + return new JsonObject + { + ["schemaVersion"] = model.SchemaVersion, + ["language"] = model.Language, + ["package"] = new JsonObject + { + ["name"] = model.Package.Name, + ["version"] = model.Package.Version + }, + ["modules"] = modules, + ["declarations"] = declarations + }; + } + + /// + /// Serializes the export document to UTF-8 JSON text. + /// + /// The model to serialize. + /// + /// When , writes human-readable JSON. Machine consumers use the compact + /// form so the document is a single line on stdout. + /// + public static string WriteToJson(TypeScriptApiModel model, bool indented = false) + => Write(model).ToJsonString(new JsonSerializerOptions { WriteIndented = indented }); + + private static JsonObject WriteModule(TypeScriptApiModule module) + { + var items = new JsonArray(); + foreach (var item in module.Items) + { + items.Add((JsonNode)WriteItem(item)); + } + + var json = new JsonObject { ["name"] = module.Name }; + AddIfPresent(json, "summary", module.Summary); + json["items"] = items; + return json; + } + + private static JsonObject WriteItem(TypeScriptApiItem item) + { + var json = new JsonObject + { + ["id"] = item.Id, + ["kind"] = ToKindString(item.Kind), + ["name"] = item.Name, + ["typeId"] = item.TypeId, + ["owningAssembly"] = item.OwningAssemblyName, + ["declaration"] = item.Declaration + }; + + AddIfPresent(json, "summary", item.Summary); + AddIfPresent(json, "remarks", item.Remarks); + AddIfPresent(json, "examples", item.Examples); + AddIfPresent(json, "extends", item.Extends); + + if (item.Members.Count > 0) + { + var members = new JsonArray(); + foreach (var member in item.Members) + { + members.Add((JsonNode)WriteMember(member)); + } + + json["members"] = members; + } + + return json; + } + + private static JsonObject WriteMember(TypeScriptApiMember member) + { + var json = new JsonObject + { + ["id"] = member.Id, + ["kind"] = ToKindString(member.Kind), + ["name"] = member.Name, + ["declaration"] = member.Declaration + }; + + AddIfPresent(json, "capabilityId", member.CapabilityId); + AddIfPresent(json, "returnType", member.ReturnType); + AddIfPresent(json, "summary", member.Summary); + AddIfPresent(json, "remarks", member.Remarks); + AddIfPresent(json, "examples", member.Examples); + AddIfPresent(json, "deprecated", member.DeprecationMessage); + + if (member.Parameters.Count > 0) + { + var parameters = new JsonArray(); + foreach (var parameter in member.Parameters) + { + var parameterJson = new JsonObject + { + ["name"] = parameter.Name, + ["type"] = parameter.DeclaredType, + ["optional"] = parameter.IsOptional + }; + + AddIfPresent(parameterJson, "summary", parameter.Summary); + parameters.Add((JsonNode)parameterJson); + } + + json["parameters"] = parameters; + } + + return json; + } + + private static string ToKindString(TypeScriptApiItemKind kind) => kind switch + { + TypeScriptApiItemKind.Interface => "interface", + TypeScriptApiItemKind.Enum => "enum", + TypeScriptApiItemKind.Dto => "dto", + TypeScriptApiItemKind.Options => "options", + TypeScriptApiItemKind.Method => "method", + TypeScriptApiItemKind.Property => "property", + _ => throw new ArgumentOutOfRangeException(nameof(kind), kind, "Unknown API item kind.") + }; + + private static void AddIfPresent(JsonObject json, string name, string? value) + { + if (!string.IsNullOrEmpty(value)) + { + json[name] = value; + } + } + + private static void AddIfPresent(JsonObject json, string name, IReadOnlyList values) + { + if (values.Count == 0) + { + return; + } + + var array = new JsonArray(); + foreach (var value in values) + { + array.Add((JsonNode)JsonValue.Create(value)); + } + + json[name] = array; + } +} diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs new file mode 100644 index 00000000000..87dbc8d91d2 --- /dev/null +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs @@ -0,0 +1,257 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Aspire.TypeSystem; + +namespace Aspire.Hosting.CodeGeneration.TypeScript; + +/// +/// The kind of a symbol in the canonical TypeScript API export. +/// +internal enum TypeScriptApiItemKind +{ + /// A generated wrapper interface for a handle type. + Interface, + + /// A generated enum. + Enum, + + /// A generated interface for an [AspireDto] type. + Dto, + + /// A generated options bag interface for a method's optional parameters. + Options, + + /// A method on a generated interface, or a module-level entry point function. + Method, + + /// A property on a generated interface. + Property, +} + +/// +/// The exact package identity a canonical export was produced for. +/// +/// The package name, for example Aspire.Hosting.Redis. +/// The exact package version, for example 13.5.0. +internal sealed record TypeScriptApiPackageIdentity(string Name, string Version); + +/// +/// A single parameter of a resolved TypeScript signature. +/// +internal sealed record TypeScriptApiParameter +{ + /// Gets the parameter name as it appears in the generated signature. + public required string Name { get; init; } + + /// Gets the final TypeScript type text for the parameter. + public required string DeclaredType { get; init; } + + /// Gets a value indicating whether the parameter is optional. + public required bool IsOptional { get; init; } + + /// Gets the documentation summary for the parameter, if any. + public string? Summary { get; init; } +} + +/// +/// A documented member of an exported item. +/// +internal sealed record TypeScriptApiMember +{ + /// Gets the stable, generator-owned identifier for the member. + public required string Id { get; init; } + + /// Gets the member kind. + public required TypeScriptApiItemKind Kind { get; init; } + + /// Gets the member name. + public required string Name { get; init; } + + /// + /// Gets the final TypeScript declaration string, for example + /// withPersistence(options?: WithPersistenceOptions): TestRedisResourceBuilderPromise. + /// + public required string Declaration { get; init; } + + /// Gets the documentation summary. + public string? Summary { get; init; } + + /// Gets the documentation remarks. + public string? Remarks { get; init; } + + /// Gets the documentation examples. + public IReadOnlyList Examples { get; init; } = []; + + /// Gets the deprecation message, or when the member is not deprecated. + public string? DeprecationMessage { get; init; } + + /// Gets the ATS capability that produced this member, used as source metadata. + public string? CapabilityId { get; init; } + + /// + /// Gets the assembly that declares this member, which is not always the assembly that owns the + /// type it hangs off: a package can add extension methods to another package's resource. + /// + public string? OwningAssemblyName { get; init; } + + /// Gets the resolved parameters of the member. + public IReadOnlyList Parameters { get; init; } = []; + + /// Gets the final TypeScript return type text, if the member has one. + public string? ReturnType { get; init; } +} + +/// +/// A documented, package-owned top-level symbol. +/// +internal sealed record TypeScriptApiItem +{ + /// Gets the stable, generator-owned identifier for the item. + public required string Id { get; init; } + + /// Gets the ATS type identifier the item was projected from, when it has one. + public required string TypeId { get; init; } + + /// Gets the item kind. + public required TypeScriptApiItemKind Kind { get; init; } + + /// Gets the generated TypeScript name. + public required string Name { get; init; } + + /// Gets the final TypeScript declaration header for the item. + public required string Declaration { get; init; } + + /// Gets the assembly that owns the item. + public required string OwningAssemblyName { get; init; } + + /// Gets the documentation summary. + public string? Summary { get; init; } + + /// Gets the documentation remarks. + public string? Remarks { get; init; } + + /// Gets the documentation examples. + public IReadOnlyList Examples { get; init; } = []; + + /// Gets the interfaces this item extends, for relationship rendering. + public IReadOnlyList Extends { get; init; } = []; + + /// Gets the documented members of the item. + public IReadOnlyList Members { get; init; } = []; +} + +/// +/// A module of package-owned documentation symbols. +/// +internal sealed record TypeScriptApiModule +{ + /// Gets the module name. + public required string Name { get; init; } + + /// Gets the module summary. + public string? Summary { get; init; } + + /// Gets the package-owned items in the module. + public required IReadOnlyList Items { get; init; } +} + +/// +/// A generator-owned TypeScript declaration fragment. +/// +/// +/// Concatenating the fragments of one complete manifest, ordered and deduplicated by +/// , must type-check on its own. Fragments contributed by the referenced-type +/// closure carry the owning assembly of the referenced type so consumers can avoid creating +/// duplicate documentation pages for another package's symbols. +/// +internal sealed record TypeScriptApiDeclaration +{ + /// Gets the stable, generator-owned identifier used for ordering and deduplication. + public required string Id { get; init; } + + /// Gets the TypeScript declaration text. + public required string Content { get; init; } + + /// Gets the assembly that owns the declared symbol. + public required string OwningAssemblyName { get; init; } +} + +/// +/// The canonical TypeScript API export model for one package. +/// +internal sealed record TypeScriptApiModel +{ + /// Gets the export schema version. + public required int SchemaVersion { get; init; } + + /// Gets the export language, always typescript. + public required string Language { get; init; } + + /// Gets the exact package identity this export was produced for. + public required TypeScriptApiPackageIdentity Package { get; init; } + + /// Gets the package-owned documentation modules. + public required IReadOnlyList Modules { get; init; } + + /// Gets the declaration fragments needed to type-check the exported surface. + public required IReadOnlyList Declarations { get; init; } +} + +/// +/// A method signature resolved once and shared by the source emitter and the canonical exporter. +/// +/// +/// Both emitters must render the same text. Reconstructing signatures separately is what caused +/// documented TypeScript signatures to drift from the generated SDK (microsoft/aspire#17608). +/// +internal sealed record TypeScriptApiMethodSignature +{ + /// Gets the generated method name. + public required string MethodName { get; init; } + + /// Gets the rendered public parameter list, without the surrounding parentheses. + public required string ParameterList { get; init; } + + /// Gets the final TypeScript return type text. + public required string ReturnType { get; init; } + + /// Gets the required parameters, in declaration order. + public required IReadOnlyList RequiredParameters { get; init; } + + /// Gets the optional parameters, in declaration order. + public required IReadOnlyList OptionalParameters { get; init; } + + /// Gets a value indicating whether the method exposes an options bag. + public required bool HasOptions { get; init; } + + /// Gets the options type name used for the options bag parameter. + public required string OptionsTypeName { get; init; } + + /// Gets the full declaration string, for example addRedis(name: string): RedisResourceBuilderPromise. + public string Declaration => $"{MethodName}({ParameterList}): {ReturnType}"; +} + +/// +/// The result of resolving an into TypeScript-specific decisions. +/// +internal sealed record TypeScriptResolvedModel +{ + /// Gets the ATS context the model was resolved from. + public required AtsContext Context { get; init; } + + /// Gets every builder model discovered from the context. + public required List Builders { get; init; } + + /// Gets the builders that represent resource builders. + public required List ResourceBuilders { get; init; } + + /// Gets the builders that represent context and wrapper type classes. + public required List TypeClasses { get; init; } + + /// Gets the entry point capabilities that hang off the client rather than a type. + public required List ClientMethods { get; init; } + + /// Gets the type IDs that need generated handle aliases. + public required HashSet HandleTypeIds { get; init; } +} diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs new file mode 100644 index 00000000000..db87397d7e7 --- /dev/null +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -0,0 +1,2329 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text; +using System.Text.RegularExpressions; +using Aspire.Shared.CodeGeneration; +using Aspire.TypeSystem; + +namespace Aspire.Hosting.CodeGeneration.TypeScript; + +/// +/// Resolves an into the TypeScript-specific decisions that define the +/// public SDK surface: type mapping, options flattening, callback shaping, promise wrapping, and +/// fluent return selection. +/// +/// +/// +/// This type is the single owner of those decisions. +/// consumes it to emit runtime source, and consumes the +/// same resolved model to emit the canonical API export. Documentation that reconstructs +/// signatures from raw ATS instead drifts from the SDK that actually ships, which is the failure +/// mode tracked by microsoft/aspire#17608. +/// +/// +/// Resolution happens in the constructor so the mapping members can never be called before the +/// wrapper class and options interface tables they depend on exist. +/// +/// +internal sealed partial class TypeScriptApiProjector +{ + /// The schema version of the canonical export document this projector produces. + public const int ExportSchemaVersion = 1; + + /// + /// Base library symbols that generated declarations reference but that the SDK ships by hand in + /// base.mts/transport.mts rather than generating per package. They are emitted as a + /// single declaration fragment with a well-known ID so that concatenating the fragments of a + /// complete manifest type-checks without site-authored shims, and so that deduplication by ID + /// collapses the copies contributed by every package in the manifest to exactly one. + /// + private const string RuntimeDeclarationId = "aspire:runtime:base"; + + /// The symbol names already declares. + private static readonly HashSet s_runtimeDeclaredNames = new(StringComparer.Ordinal) + { + "Awaitable", "MarshalledHandle", "HandleReference", "CancellationToken", "ReferenceExpression", + "AspireList", "AspireDict", "ResourceBuilderBase", "InteractionInput", + "InteractionInputCollection", "InteractionInputCollectionPromise" + }; + + private const string RuntimeDeclarationContent = """ + export type Awaitable = T | PromiseLike; + export interface MarshalledHandle { $handle: string; } + export interface HandleReference { toJSON(): MarshalledHandle; } + export interface CancellationToken { readonly aborted: boolean; } + export interface ReferenceExpression { readonly value: Promise; } + export interface AspireList extends HandleReference { get(index: number): Promise; } + export interface AspireDict extends HandleReference { get(key: TKey): Promise; } + export interface ResourceBuilderBase extends HandleReference {} + export interface InteractionInput { readonly name: string; } + export interface InteractionInputCollection extends HandleReference {} + export interface InteractionInputCollectionPromise extends PromiseLike {} + """; + + private readonly TypeScriptResolvedModel _resolved; + + public TypeScriptApiProjector(AtsContext context) + { + ArgumentNullException.ThrowIfNull(context); + _resolved = Resolve(context); + } + + /// Gets the resolved projection of the context this projector was built from. + internal TypeScriptResolvedModel Resolved => _resolved; + + /// Gets the mapping of ATS type ID to generated wrapper class name. + internal Dictionary WrapperClassNames => _wrapperClassNames; + + /// Gets the mapping of ATS type ID to the type reference it was resolved from. + internal Dictionary TypeRefsById => _typeRefsById; + + /// Gets the type IDs that have generated Promise wrappers. + internal HashSet TypesWithPromiseWrappers => _typesWithPromiseWrappers; + + /// Gets the names of options interfaces that have been registered for generation. + internal HashSet GeneratedOptionsInterfaces => _generatedOptionsInterfaces; + + /// Gets the options interfaces to generate, keyed by interface name. + internal Dictionary> OptionsInterfacesToGenerate => _optionsInterfacesToGenerate; + + /// Gets the mapping of capability ID to the options interface name it uses. + internal Dictionary CapabilityOptionsInterfaceMap => _capabilityOptionsInterfaceMap; + + /// Gets the mapping of enum type ID to generated TypeScript enum name. + internal Dictionary EnumTypeNames => _enumTypeNames; + + /// Gets the XML documentation captured for handle types during ATS scanning. + internal Dictionary HandleDocumentationById => _handleDocumentationById; + + /// Gets the DTO metadata used for generated argument marshalling. + internal Dictionary DtoTypesById => _dtoTypesById; + + private TypeScriptResolvedModel Resolve(AtsContext context) + { + var capabilities = context.Capabilities; + var dtoTypes = context.DtoTypes; + + var builders = CreateBuilderModels(capabilities); + var clientMethods = GetEntryPointCapabilities(capabilities) + .Where(c => string.IsNullOrEmpty(c.TargetTypeId)) + .ToList(); + + // Collect all unique type IDs for handle type aliases. + // Exclude DTO types - they have their own interfaces, not handle aliases. + var dtoTypeIds = new HashSet(dtoTypes.Select(d => d.TypeId), StringComparer.Ordinal); + var typeIds = new HashSet(StringComparer.Ordinal); + foreach (var typeId in CollectAllReferencedTypes(capabilities).Keys) + { + if (!dtoTypeIds.Contains(typeId)) + { + typeIds.Add(typeId); + } + } + + // Ensure all builder type IDs have handle type aliases. + // CreateBuilderModels discovers additional resource types via CollectAllReferencedTypes + // (e.g. types that appear only in return types or parameters but aren't direct capability targets). + // Without this, the builder class references a handle type that was never declared. + foreach (var builder in builders) + { + if (!dtoTypeIds.Contains(builder.TypeId)) + { + typeIds.Add(builder.TypeId); + } + } + + // Separate builders into categories: + // 1. Resource builders: IResource*, ContainerResource, etc. + // 2. Type classes: everything else (context types, wrapper types) + var resourceBuilders = builders.Where(b => b.TargetType?.IsResourceBuilder == true).ToList(); + var typeClasses = builders.Where(b => b.TargetType?.IsResourceBuilder != true).ToList(); + + // Build wrapper class name mapping before anything consumes the mappings so callback + // properties can reference wrapper classes instead of raw handle aliases. + _wrapperClassNames.Clear(); + _typeRefsById.Clear(); + _typesWithPromiseWrappers.Clear(); + _generatedOptionsInterfaces.Clear(); + _optionsInterfacesToGenerate.Clear(); + _capabilityOptionsInterfaceMap.Clear(); + _handleDocumentationById.Clear(); + _dtoTypesById.Clear(); + _enumTypeNames.Clear(); + + foreach (var dtoType in dtoTypes) + { + _dtoTypesById[dtoType.TypeId] = dtoType; + } + + foreach (var handleType in context.HandleTypes) + { + if (handleType.Documentation is not null) + { + _handleDocumentationById[handleType.AtsTypeId] = handleType.Documentation; + } + } + + foreach (var builder in resourceBuilders) + { + _wrapperClassNames[builder.TypeId] = builder.BuilderClassName; + if (builder.TargetType is { } targetType) + { + _typeRefsById[builder.TypeId] = targetType; + } + // All resource builders get Promise wrappers + _typesWithPromiseWrappers.Add(builder.TypeId); + } + + foreach (var typeClass in typeClasses) + { + _wrapperClassNames[typeClass.TypeId] = DeriveClassName(typeClass.TypeId); + if (typeClass.TargetType is { } targetType) + { + _typeRefsById[typeClass.TypeId] = targetType; + } + // Type classes with methods get Promise wrappers + if (HasChainableMethods(typeClass)) + { + _typesWithPromiseWrappers.Add(typeClass.TypeId); + } + } + + // InteractionInputCollection is a hand-written base.mts type: its by-name accessors + // (value/get/required/requiredValue) are client-side conveniences, not ATS capabilities, so + // it is never registered as a generated type class. Register it as a promise-wrapper type so + // collection-returning getters (result.inputs(), validationContext.inputs(), command + // arguments()) emit the fluent InteractionInputCollectionPromise thenable instead of a bare + // Promise. That lets callers chain `await x.inputs().value("c")` + // without an intermediate await, matching the C#/Go/Java/Python surfaces. The wrapper + // (InteractionInputCollectionPromise / InteractionInputCollectionPromiseImpl) is hand-written + // in base.mts; it is intentionally absent from the wrapper class table so the getter impl + // keeps using the marshaller-based collection construction rather than a handle+Impl wrapper. + _typesWithPromiseWrappers.Add(InteractionInputCollectionTypeId); + // Note: ReferenceExpression is intentionally NOT added to the wrapper class table. + // It is a value type defined in base.mts with a private constructor and static factory, + // not a handle-based wrapper. It is handled via MapTypeRefToTypeScript instead. + + // Enum names are a resolution decision, not an emission detail: MapEnumType has to resolve + // them while options interfaces are being registered, which happens before any enum is + // written out. + _enumTypeNames[InputTypeTypeId] = GetInputTypeEnumName(); + foreach (var enumType in context.EnumTypes.Where(e => e.TypeId != InputTypeTypeId)) + { + _enumTypeNames[enumType.TypeId] = enumType.Name; + } + + // Pre-scan all capabilities to collect options interfaces. + // This must happen AFTER wrapper class names are populated so types resolve correctly. + foreach (var builder in builders) + { + foreach (var cap in builder.Capabilities) + { + var (_, optionalParams) = SeparateParameters(cap.Parameters); + if (optionalParams.Count > 0 && !TryGetDirectOptionsParameter(optionalParams, out _)) + { + RegisterOptionsInterface(cap.CapabilityId, cap.MethodName, optionalParams); + } + } + } + + return new TypeScriptResolvedModel + { + Context = context, + Builders = builders, + ResourceBuilders = resourceBuilders, + TypeClasses = typeClasses, + ClientMethods = clientMethods, + HandleTypeIds = typeIds + }; + } + + /// + /// Resolves the public signature of a capability exactly once so the source emitter and the + /// canonical exporter cannot disagree about parameter shaping or return type selection. + /// + /// The builder the capability is rendered on, or for a client entry point. + /// The capability to resolve. + /// + /// Resource builders and type classes shape methods differently: they bind a different default + /// target parameter name, derive the method name differently, and pick fluent return types by + /// different rules. Both rules live here so neither emitter has to reimplement them. + /// + internal TypeScriptApiMethodSignature ResolveMethodSignature(BuilderModel? builder, AtsCapabilityInfo capability) + { + ArgumentNullException.ThrowIfNull(capability); + + var isTypeClass = builder is not null && builder.TargetType?.IsResourceBuilder != true; + var targetParamName = capability.TargetParameterName ?? (isTypeClass ? "context" : "builder"); + var userParams = builder is null + ? [.. capability.Parameters] + : capability.Parameters.Where(p => p.Name != targetParamName).ToList(); + + var (requiredParams, optionalParams) = SeparateParameters(userParams); + var hasOptionals = optionalParams.Count > 0; + var hasDirectOptionsParameter = TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); + var optionsTypeName = hasDirectOptionsParameter + ? MapParameterToTypeScript(directOptionsParam!) + : ResolveOptionsInterfaceName(capability); + var parameterList = BuildPublicParameterList( + requiredParams, + hasOptionals, + optionsTypeName, + trailingCancellationToken: GetTrailingCancellationTokenParameter(optionalParams)); + + return new TypeScriptApiMethodSignature + { + MethodName = isTypeClass ? ResolveTypeClassMethodName(capability) : capability.MethodName, + ParameterList = parameterList, + ReturnType = isTypeClass + ? ResolveTypeClassReturnType(builder!, capability) + : ResolveBuilderReturnType(builder, capability), + RequiredParameters = requiredParams, + OptionalParameters = optionalParams, + HasOptions = hasOptionals, + OptionsTypeName = optionsTypeName + }; + } + + /// + /// Strips the declaring type prefix from an explicitly implemented member. + /// + /// + /// Capabilities on an interface implementation carry the qualified C# name, for example + /// IValueProvider.GetValueAsync. TypeScript has no explicit interface implementation, so + /// only the trailing member name is emitted. + /// + private static string ResolveTypeClassMethodName(AtsCapabilityInfo capability) + => !string.IsNullOrEmpty(capability.OwningTypeName) && capability.MethodName.Contains('.') + ? capability.MethodName[(capability.MethodName.LastIndexOf('.') + 1)..] + : GetTypeScriptMethodName(capability.MethodName); + + /// + /// Selects the return type for a method on a resource builder: a promise wrapper when the + /// non-builder return type has one, a plain Promise<T> when it does not, and the + /// owning builder's fluent promise interface when the method chains. + /// + private string ResolveBuilderReturnType(BuilderModel? builder, AtsCapabilityInfo capability) + { + var hasNonBuilderReturn = !capability.ReturnsBuilder && capability.ReturnType is not null; + + if (hasNonBuilderReturn) + { + return TryGetPromiseWrapperType(capability.ReturnType, out var promiseInterfaceName, out _) + ? promiseInterfaceName + : $"Promise<{MapTypeRefToTypeScript(capability.ReturnType)}>"; + } + + if (builder is not null) + { + return GetBuilderPromiseInterfaceForMethod(builder, capability); + } + + // Entry points have no owning builder, so the fluent return comes from the return type itself. + return capability.ReturnType is { TypeId: { } returnTypeId } + ? GetPublicPromiseInterfaceName(returnTypeId) + : "Promise"; + } + + /// + /// Selects the return type for a method on a type class. Void-returning methods chain on the + /// owning class rather than resolving to Promise<void>, which is what makes context + /// types fluent. + /// + private string ResolveTypeClassReturnType(BuilderModel builder, AtsCapabilityInfo capability) + { + if (capability.ReturnType is { } returnType && _typesWithPromiseWrappers.Contains(returnType.TypeId)) + { + return GetPublicPromiseInterfaceName(returnType.TypeId); + } + + if (capability.ReturnType is null || capability.ReturnType.TypeId == AtsConstants.Void) + { + return GetPromiseInterfaceName(DeriveClassName(builder.TypeId)); + } + + return $"Promise<{MapTypeRefToTypeScript(capability.ReturnType)}>"; + } + + /// + /// Builds the canonical API export model for one package from the already-resolved projection. + /// + /// + /// Declaration fragment IDs are keyed by the assembly that owns the symbol rather than by the + /// exporting package, so a manifest that concatenates several packages collapses shared + /// referenced types to a single declaration instead of one copy per package. + /// + /// The exact package identity the export is produced for. + /// + /// The assemblies whose symbols the package owns. Symbols outside this set reached the context + /// through the referenced-type closure: they contribute declaration fragments so the export + /// type-checks, but they must not produce documentation pages here. + /// + internal TypeScriptApiModel BuildApiModel( + TypeScriptApiPackageIdentity package, + IReadOnlyCollection ownedAssemblyNames) + { + ArgumentNullException.ThrowIfNull(package); + ArgumentNullException.ThrowIfNull(ownedAssemblyNames); + + var owned = new HashSet(ownedAssemblyNames, StringComparer.OrdinalIgnoreCase); + + var items = new List(); + var declarations = new Dictionary(StringComparer.Ordinal) + { + [RuntimeDeclarationId] = new TypeScriptApiDeclaration + { + Id = RuntimeDeclarationId, + Content = RuntimeDeclarationContent, + OwningAssemblyName = "Aspire.Hosting" + } + }; + + foreach (var builderModel in _resolved.Builders.OrderBy(b => b.BuilderClassName, StringComparer.Ordinal)) + { + var (item, builderDeclarations) = ProjectBuilder(package, builderModel, owned); + + foreach (var declaration in builderDeclarations) + { + declarations[declaration.Id] = declaration; + } + + if (item is not null) + { + items.Add(item); + } + } + + foreach (var entryPoint in _resolved.ClientMethods.OrderBy(c => c.MethodName, StringComparer.Ordinal)) + { + if (!owned.Contains(GetCapabilityOwningAssemblyName(entryPoint))) + { + continue; + } + + items.Add(ProjectEntryPoint(package, entryPoint)); + } + + foreach (var enumType in _resolved.Context.EnumTypes + .Where(e => e.TypeId != InputTypeTypeId) + .OrderBy(e => e.Name, StringComparer.Ordinal)) + { + var (item, declaration) = ProjectEnum(enumType); + + declarations[declaration.Id] = declaration; + + if (owned.Contains(item.OwningAssemblyName)) + { + items.Add(item); + } + } + + foreach (var dtoType in _resolved.Context.DtoTypes + .Where(d => d.TypeId != InteractionInputTypeId) + .OrderBy(d => d.TypeId, StringComparer.Ordinal)) + { + var (item, declaration) = ProjectDto(dtoType); + + declarations[declaration.Id] = declaration; + + if (owned.Contains(item.OwningAssemblyName)) + { + items.Add(item); + } + } + + // Options interfaces are generated per method name rather than per type, so they are always + // package-owned when the method that produced them is. + foreach (var (interfaceName, optionalParams) in _optionsInterfacesToGenerate.OrderBy(kvp => kvp.Key, StringComparer.Ordinal)) + { + var (item, declaration) = ProjectOptionsInterface(package, interfaceName, optionalParams); + + declarations[declaration.Id] = declaration; + items.Add(item); + } + + // Types reached through the referenced-type closure are named by generated unions and + // parameters but have no capabilities of their own in this context, so nothing above + // declared them. Emit an opaque interface for each so the concatenated declarations + // type-check standalone. They deliberately produce no documented item: the package that + // owns them publishes their real surface. + // Deduplicate by declared name rather than by type ID: several ATS type IDs can resolve to + // the same generated interface name, and emitting a stub for one of them would redeclare a + // type another fragment already declares in full. + var declaredNames = new HashSet(s_runtimeDeclaredNames, StringComparer.Ordinal); + foreach (var declaration in declarations.Values) + { + foreach (Match match in DeclaredTypeNameRegex().Matches(declaration.Content)) + { + declaredNames.Add(match.Groups[1].Value); + } + } + + foreach (var typeId in _resolved.HandleTypeIds.OrderBy(id => id, StringComparer.Ordinal)) + { + var name = GetInterfaceName(_wrapperClassNames.GetValueOrDefault(typeId) ?? DeriveClassName(typeId)); + + if (!declaredNames.Add(name)) + { + continue; + } + + var baseType = _typeRefsById.GetValueOrDefault(typeId)?.IsResourceBuilder == true + ? "ResourceBuilderBase" + : "HandleReference"; + var owningAssembly = GetTypeOwningAssemblyName(typeId); + + declarations[$"{owningAssembly}:opaque:{name}"] = new TypeScriptApiDeclaration + { + Id = $"{owningAssembly}:opaque:{name}", + Content = $"export interface {name} extends {baseType} {{}}", + OwningAssemblyName = owningAssembly + }; + + if (!_typesWithPromiseWrappers.Contains(typeId)) + { + continue; + } + + var promiseName = GetPromiseInterfaceName(_wrapperClassNames.GetValueOrDefault(typeId) ?? DeriveClassName(typeId)); + if (!declaredNames.Add(promiseName)) + { + continue; + } + + declarations[$"{owningAssembly}:opaque:{promiseName}"] = new TypeScriptApiDeclaration + { + Id = $"{owningAssembly}:opaque:{promiseName}", + Content = $"export interface {promiseName} extends PromiseLike<{name}> {{}}", + OwningAssemblyName = owningAssembly + }; + } + + var module = new TypeScriptApiModule + { + Name = package.Name, + Summary = null, + Items = [.. items.OrderBy(i => i.Id, StringComparer.Ordinal)] + }; + + return new TypeScriptApiModel + { + SchemaVersion = ExportSchemaVersion, + Language = "typescript", + Package = package, + Modules = [module], + Declarations = [.. declarations.Values.OrderBy(d => d.Id, StringComparer.Ordinal)] + }; + } + + /// + /// Projects one builder into an optional documented item plus the declaration fragments it + /// contributes. + /// + /// + /// A package can extend a type another package owns. When that happens the type itself is not + /// documented here — the owning package publishes it — but the members this package contributes + /// still are, and they are emitted as a separate interface augmentation fragment so TypeScript + /// declaration merging reassembles the full type when a manifest concatenates every package. + /// + private (TypeScriptApiItem? Item, List Declarations) ProjectBuilder( + TypeScriptApiPackageIdentity package, + BuilderModel builderModel, + HashSet ownedAssemblyNames) + { + var isResourceBuilder = builderModel.TargetType?.IsResourceBuilder == true; + var interfaceName = GetInterfaceName(isResourceBuilder + ? builderModel.BuilderClassName + : DeriveClassName(builderModel.TypeId)); + var members = new List(); + + var getters = builderModel.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); + var setters = builderModel.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); + + foreach (var property in GroupPropertiesByName(getters, setters)) + { + members.Add(ProjectProperty(interfaceName, property.PropertyName, property.Getter, property.Setter)); + } + + // Type classes only surface instance and static methods; resource builders surface every + // non-property capability. Mirroring that split keeps the export aligned with the interfaces + // the generator actually writes. + var methods = isResourceBuilder + ? builderModel.Capabilities.Where(c => + c.CapabilityKind != AtsCapabilityKind.PropertyGetter && + c.CapabilityKind != AtsCapabilityKind.PropertySetter) + : builderModel.Capabilities.Where(c => + c.CapabilityKind is AtsCapabilityKind.InstanceMethod or AtsCapabilityKind.Method); + + foreach (var capability in methods) + { + members.Add(ProjectMethod(interfaceName, builderModel, capability)); + } + + var documentation = _handleDocumentationById.GetValueOrDefault(builderModel.TypeId); + string[] extends = isResourceBuilder ? ["ResourceBuilderBase"] : []; + var typeOwner = GetTypeOwningAssemblyName(builderModel.TypeId); + var declarations = new List(); + + // Every method returns the owning type's fluent promise interface, so the promise interface + // has to be declared alongside the interface or the fragments cannot type-check. + var promiseInterfaceName = _typesWithPromiseWrappers.Contains(builderModel.TypeId) + ? GetPromiseInterfaceName(isResourceBuilder ? builderModel.BuilderClassName : DeriveClassName(builderModel.TypeId)) + : null; + + if (ownedAssemblyNames.Contains(typeOwner)) + { + declarations.Add(new TypeScriptApiDeclaration + { + Id = $"{typeOwner}:interface:{interfaceName}", + Content = BuildInterfaceBody(interfaceName, extends, members, includeToJson: true), + OwningAssemblyName = typeOwner + }); + + if (promiseInterfaceName is not null) + { + declarations.Add(new TypeScriptApiDeclaration + { + Id = $"{typeOwner}:interface:{promiseInterfaceName}", + Content = BuildInterfaceBody(promiseInterfaceName, [$"PromiseLike<{interfaceName}>"], members, includeToJson: false), + OwningAssemblyName = typeOwner + }); + } + + return (BuildInterfaceItem(builderModel, interfaceName, extends, typeOwner, documentation, members), declarations); + } + + // The referenced type gets an opaque stub keyed by its real owner so every package that + // references it contributes the identical fragment and deduplication collapses them. + declarations.Add(new TypeScriptApiDeclaration + { + Id = $"{typeOwner}:opaque:{interfaceName}", + Content = $"export interface {interfaceName} extends {(isResourceBuilder ? "ResourceBuilderBase" : "HandleReference")} {{}}", + OwningAssemblyName = typeOwner + }); + + if (promiseInterfaceName is not null) + { + declarations.Add(new TypeScriptApiDeclaration + { + Id = $"{typeOwner}:opaque:{promiseInterfaceName}", + Content = $"export interface {promiseInterfaceName} extends PromiseLike<{interfaceName}> {{}}", + OwningAssemblyName = typeOwner + }); + } + + var contributedMembers = members + .Where(member => member.OwningAssemblyName is { } memberOwner && ownedAssemblyNames.Contains(memberOwner)) + .ToList(); + + if (contributedMembers.Count == 0) + { + return (null, declarations); + } + + declarations.Add(new TypeScriptApiDeclaration + { + Id = $"{package.Name}:augment:{interfaceName}", + Content = BuildInterfaceBody(interfaceName, [], contributedMembers, includeToJson: false), + OwningAssemblyName = package.Name + }); + + if (promiseInterfaceName is not null) + { + declarations.Add(new TypeScriptApiDeclaration + { + Id = $"{package.Name}:augment:{promiseInterfaceName}", + Content = BuildInterfaceBody(promiseInterfaceName, [], contributedMembers, includeToJson: false), + OwningAssemblyName = package.Name + }); + } + + return (BuildInterfaceItem(builderModel, interfaceName, extends, package.Name, documentation, contributedMembers), declarations); + } + + private static TypeScriptApiItem BuildInterfaceItem( + BuilderModel builderModel, + string interfaceName, + string[] extends, + string owningAssemblyName, + AtsDocumentationInfo? documentation, + List members) + => new() + { + Id = $"interface:{interfaceName}", + TypeId = builderModel.TypeId, + Kind = TypeScriptApiItemKind.Interface, + Name = interfaceName, + Declaration = BuildInterfaceHeader(interfaceName, extends), + OwningAssemblyName = owningAssemblyName, + Summary = documentation?.Summary, + Remarks = documentation?.Remarks, + Extends = extends, + Members = members + }; + + /// + /// Matches the name a declaration fragment declares, for example the RedisResource in + /// export interface RedisResource extends ResourceBuilderBase {. + /// + [GeneratedRegex(@"^export (?:interface|enum|type) (\w+)", RegexOptions.Multiline)] + private static partial Regex DeclaredTypeNameRegex(); + + private static string BuildInterfaceBody( + string interfaceName, + IReadOnlyList extends, + List members, + bool includeToJson) + { + var body = new StringBuilder(); + body.Append(BuildInterfaceHeader(interfaceName, extends)).Append(" {\n"); + + if (includeToJson) + { + body.Append(" toJSON(): MarshalledHandle;\n"); + } + + foreach (var member in members) + { + body.Append(" ").Append(member.Declaration).Append(";\n"); + } + + return body.Append('}').ToString(); + } + + private TypeScriptApiMember ProjectMethod( + string ownerName, + BuilderModel? builderModel, + AtsCapabilityInfo capability) + { + var signature = ResolveMethodSignature(builderModel, capability); + var targetParamName = capability.TargetParameterName ?? "builder"; + + var parameters = capability.Parameters + .Where(p => builderModel is null || p.Name != targetParamName) + .Select(p => new TypeScriptApiParameter + { + Name = p.Name, + DeclaredType = MapParameterToTypeScript(p), + IsOptional = p.IsOptional || p.IsNullable, + Summary = p.Documentation?.Summary + }) + .ToList(); + + return new TypeScriptApiMember + { + Id = $"method:{ownerName}.{capability.MethodName}", + Kind = TypeScriptApiItemKind.Method, + Name = capability.MethodName, + Declaration = signature.Declaration, + Summary = capability.Documentation?.Summary, + Remarks = capability.Documentation?.Remarks, + DeprecationMessage = capability.IsObsolete ? capability.ObsoleteMessage ?? string.Empty : null, + CapabilityId = capability.CapabilityId, + OwningAssemblyName = GetCapabilityOwningAssemblyName(capability), + Parameters = parameters, + ReturnType = signature.ReturnType + }; + } + + private TypeScriptApiMember ProjectProperty( + string ownerName, + string propertyName, + AtsCapabilityInfo? getter, + AtsCapabilityInfo? setter) + { + string declaration; + + if (IsGetterOnlyProperty(getter, setter)) + { + declaration = $"{propertyName}(): {GetGetterOnlyPropertyMethodReturnType(getter!.ReturnType)}"; + } + else if (getter?.ReturnType is { } returnType && IsDictionaryType(returnType)) + { + var keyType = returnType.KeyType is not null ? MapTypeRefToTypeScript(returnType.KeyType) : "string"; + var valueType = returnType.ValueType is not null ? MapTypeRefToTypeScript(returnType.ValueType) : "unknown"; + declaration = $"readonly {propertyName}: AspireDict<{keyType}, {valueType}>"; + } + else if (getter?.ReturnType is { } listReturnType && IsListType(listReturnType)) + { + var elementType = listReturnType.ElementType is not null ? MapTypeRefToTypeScript(listReturnType.ElementType) : "unknown"; + declaration = $"readonly {propertyName}: AspireList<{elementType}>"; + } + else + { + var accessors = new List(); + if (getter is not null) + { + var getReturn = TryGetPromiseWrapperType(getter.ReturnType, out var promiseInterfaceName, out _) + ? promiseInterfaceName + : $"Promise<{MapTypeRefToTypeScript(getter.ReturnType)}>"; + accessors.Add($"get: () => {getReturn}"); + } + + if (setter?.Parameters.FirstOrDefault(p => p.Name == "value") is { } valueParam) + { + accessors.Add($"set: (value: {MapInputTypeToTypeScript(valueParam.Type)}) => Promise"); + } + + declaration = $"{propertyName}: {{ {string.Join("; ", accessors)} }}"; + } + + var documentation = getter?.Documentation ?? setter?.Documentation; + + return new TypeScriptApiMember + { + Id = $"property:{ownerName}.{propertyName}", + Kind = TypeScriptApiItemKind.Property, + Name = propertyName, + Declaration = declaration, + Summary = documentation?.Summary, + Remarks = documentation?.Remarks, + DeprecationMessage = (getter ?? setter) is { IsObsolete: true } obsolete ? obsolete.ObsoleteMessage ?? string.Empty : null, + CapabilityId = (getter ?? setter)?.CapabilityId, + OwningAssemblyName = (getter ?? setter) is { } capability ? GetCapabilityOwningAssemblyName(capability) : null + }; + } + + private TypeScriptApiItem ProjectEntryPoint(TypeScriptApiPackageIdentity package, AtsCapabilityInfo capability) + { + var member = ProjectMethod(package.Name, builderModel: null, capability); + + return new TypeScriptApiItem + { + Id = $"method:{capability.MethodName}", + TypeId = capability.CapabilityId, + Kind = TypeScriptApiItemKind.Method, + Name = capability.MethodName, + Declaration = member.Declaration, + OwningAssemblyName = GetCapabilityOwningAssemblyName(capability), + Summary = member.Summary, + Remarks = member.Remarks, + Members = [] + }; + } + + private static (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) ProjectEnum(AtsEnumTypeInfo enumType) + { + var owningAssemblyName = GetOwningAssemblyName(enumType.TypeId, enumType.ClrType?.Assembly.GetName().Name); + + var values = enumType.ValueInfos.Count > 0 + ? enumType.ValueInfos + : [.. enumType.Values.Select(value => new AtsEnumValueInfo { Name = value })]; + + var members = values + .Select(value => new TypeScriptApiMember + { + Id = $"enumValue:{enumType.Name}.{value.Name}", + Kind = TypeScriptApiItemKind.Property, + Name = value.Name, + Declaration = $"{value.Name} = \"{value.Name}\"", + Summary = value.Documentation?.Summary, + OwningAssemblyName = owningAssemblyName + }) + .ToList(); + + var item = new TypeScriptApiItem + { + Id = $"enum:{enumType.Name}", + TypeId = enumType.TypeId, + Kind = TypeScriptApiItemKind.Enum, + Name = enumType.Name, + Declaration = $"export enum {enumType.Name}", + OwningAssemblyName = owningAssemblyName, + Summary = enumType.Documentation?.Summary, + Remarks = enumType.Documentation?.Remarks, + Members = members + }; + + var body = new StringBuilder(); + body.Append("export enum ").Append(enumType.Name).Append(" {\n"); + foreach (var member in members) + { + body.Append(" ").Append(member.Declaration).Append(",\n"); + } + body.Append('}'); + + return (item, new TypeScriptApiDeclaration + { + Id = $"{item.OwningAssemblyName}:enum:{enumType.Name}", + Content = body.ToString(), + OwningAssemblyName = item.OwningAssemblyName + }); + } + + private (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) ProjectDto(AtsDtoTypeInfo dtoType) + { + var interfaceName = GetDtoInterfaceName(dtoType.TypeId); + var owningAssemblyName = GetOwningAssemblyName(dtoType.TypeId, dtoType.ClrType?.Assembly.GetName().Name); + + var members = dtoType.Properties + .Select(property => + { + var propertyName = ToCamelCase(property.Name); + var propertyType = property.IsCallback + ? GenerateCallbackTypeSignature(property.CallbackParameters, property.CallbackReturnType) + : MapDtoPropertyTypeToTypeScript(property.Type); + return new TypeScriptApiMember + { + Id = $"property:{interfaceName}.{propertyName}", + Kind = TypeScriptApiItemKind.Property, + Name = propertyName, + Declaration = $"{propertyName}?: {propertyType}", + Summary = property.Documentation?.Summary ?? property.Description, + OwningAssemblyName = owningAssemblyName + }; + }) + .ToList(); + + var item = new TypeScriptApiItem + { + Id = $"dto:{interfaceName}", + TypeId = dtoType.TypeId, + Kind = TypeScriptApiItemKind.Dto, + Name = interfaceName, + Declaration = $"export interface {interfaceName}", + OwningAssemblyName = owningAssemblyName, + Summary = dtoType.Documentation?.Summary, + Remarks = dtoType.Documentation?.Remarks, + Members = members + }; + + var body = new StringBuilder(); + body.Append("export interface ").Append(interfaceName).Append(" {\n"); + foreach (var member in members) + { + body.Append(" ").Append(member.Declaration).Append(";\n"); + } + body.Append('}'); + + return (item, new TypeScriptApiDeclaration + { + Id = $"{item.OwningAssemblyName}:dto:{interfaceName}", + Content = body.ToString(), + OwningAssemblyName = item.OwningAssemblyName + }); + } + + private (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) ProjectOptionsInterface( + TypeScriptApiPackageIdentity package, + string interfaceName, + List optionalParams) + { + var members = optionalParams + .Select(param => new TypeScriptApiMember + { + Id = $"property:{interfaceName}.{param.Name}", + Kind = TypeScriptApiItemKind.Property, + Name = param.Name, + Declaration = $"{param.Name}?: {MapParameterToTypeScript(param)}", + Summary = param.Documentation?.Summary, + OwningAssemblyName = package.Name + }) + .ToList(); + + var item = new TypeScriptApiItem + { + Id = $"options:{interfaceName}", + TypeId = $"{package.Name}/{interfaceName}", + Kind = TypeScriptApiItemKind.Options, + Name = interfaceName, + Declaration = $"export interface {interfaceName}", + OwningAssemblyName = package.Name, + Members = members + }; + + var body = new StringBuilder(); + body.Append("export interface ").Append(interfaceName).Append(" {\n"); + foreach (var member in members) + { + body.Append(" ").Append(member.Declaration).Append(";\n"); + } + body.Append('}'); + + return (item, new TypeScriptApiDeclaration + { + Id = $"{package.Name}:options:{interfaceName}", + Content = body.ToString(), + OwningAssemblyName = package.Name + }); + } + + private static string BuildInterfaceHeader(string interfaceName, IReadOnlyList extends) + => extends.Count > 0 + ? $"export interface {interfaceName} extends {string.Join(", ", extends)}" + : $"export interface {interfaceName}"; + + /// + /// Resolves the owning assembly from the leading segment of an ATS identifier. + /// + /// + /// ATS identifiers are {Prefix}/{FullTypeNameOrMemberName}, for example + /// Aspire.Hosting.Redis/RedisResource or Aspire.Hosting.Redis/addRedis. The prefix + /// is usually the assembly name, but instance members carry the declaring namespace instead + /// (Contoso.Widgets.Model/WidgetContext.name), so this is only a fallback for symbols + /// that carry no CLR reflection info. Enum type IDs use the enum: prefix and have no + /// segment at all, so the caller supplies the CLR assembly name. + /// + private static string GetOwningAssemblyName(string atsId, string? clrAssemblyName = null) + { + if (clrAssemblyName is { Length: > 0 }) + { + return clrAssemblyName; + } + + var separatorIndex = atsId.IndexOf('/'); + return separatorIndex > 0 ? atsId[..separatorIndex] : string.Empty; + } + + /// + /// Resolves the assembly that owns a capability, preferring CLR reflection info over the + /// identifier prefix so that instance members — whose IDs are namespace-qualified rather than + /// assembly-qualified — are attributed to the package that actually declares them. + /// + /// + /// This mirrors AtsContextFilter.IsCapabilityOwnedBySelectedAssembly. The two must agree, + /// or the exporter would document symbols the filter excluded, or drop symbols it kept. + /// + private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) + { + if (_resolved.Context.Methods.TryGetValue(capability.CapabilityId, out var method)) + { + return method.DeclaringType?.Assembly.GetName().Name ?? string.Empty; + } + + if (_resolved.Context.Properties.TryGetValue(capability.CapabilityId, out var property)) + { + return property.DeclaringType?.Assembly.GetName().Name ?? string.Empty; + } + + return GetOwningAssemblyName(capability.CapabilityId, capability.TargetType?.ClrType?.Assembly.GetName().Name); + } + + /// + /// Resolves the assembly that owns a handle type, preferring CLR reflection info for the same + /// reason as . + /// + private string GetTypeOwningAssemblyName(string typeId) + => GetOwningAssemblyName(typeId, _typeRefsById.GetValueOrDefault(typeId)?.ClrType?.Assembly.GetName().Name); + + // Mapping of typeId -> wrapper class name for all generated wrapper types + // Used to resolve parameter types to wrapper classes instead of handle types + + private readonly Dictionary _wrapperClassNames = new(StringComparer.Ordinal); + + private readonly Dictionary _typeRefsById = new(StringComparer.Ordinal); + + // Set of type IDs that have Promise wrappers (types with chainable methods) + // Used to determine return types for methods + + private readonly HashSet _typesWithPromiseWrappers = new(StringComparer.Ordinal); + + // Set of generated options interfaces to avoid duplicates + + private readonly HashSet _generatedOptionsInterfaces = new(StringComparer.Ordinal); + + // Collected options interfaces to generate (interface name -> list of optional params) + + private readonly Dictionary> _optionsInterfacesToGenerate = new(StringComparer.Ordinal); + + // Mapping from CapabilityId to the options interface name it should use. + // When methods share a name but have incompatible callback parameter types, + // separate options interfaces are generated with numeric suffixes. + + private readonly Dictionary _capabilityOptionsInterfaceMap = new(StringComparer.Ordinal); + + // Mapping of enum type IDs to TypeScript enum names + + private readonly Dictionary _enumTypeNames = new(StringComparer.Ordinal); + + // Mapping of handle type IDs to XML documentation captured during ATS scanning. + + private readonly Dictionary _handleDocumentationById = new(StringComparer.Ordinal); + + // Mapping of DTO type IDs to DTO metadata for generated argument marshalling. + + private readonly Dictionary _dtoTypesById = new(StringComparer.Ordinal); + + internal static string GetInterfaceName(string className) => className; + + internal static string GetPromiseInterfaceName(string className) => $"{className}Promise"; + + internal static string GetImplementationClassName(string className) => $"{className}Impl"; + + internal static string GetImplementationPromiseClassName(string className) => $"{className}PromiseImpl"; + + internal static string GetReferenceExpressionInterfaceName() => "ReferenceExpression"; + + internal static string GetCancellationTokenInterfaceName() => "CancellationToken"; + + internal static string GetHandleReferenceInterfaceName() => "HandleReference"; + + internal static string GetInputTypeEnumName() => "InputType"; + + internal static string GetInteractionInputInterfaceName() => "InteractionInput"; + + internal static string GetInteractionInputCollectionClassName() => "InteractionInputCollection"; + + internal const string InputTypeTypeId = "enum:Aspire.Hosting.InputType"; + + internal const string InteractionInputTypeId = "Aspire.Hosting/Aspire.Hosting.InteractionInput"; + + internal const string InteractionInputCollectionTypeId = "Aspire.Hosting/Aspire.Hosting.InteractionInputCollection"; + + internal string GetConcreteClassName(string typeId) => _wrapperClassNames.GetValueOrDefault(typeId) + ?? DeriveClassName(typeId); + + internal string GetPublicPromiseInterfaceName(string typeId) => GetPromiseInterfaceName(GetConcreteClassName(typeId)); + + internal static bool IsHandleType(AtsTypeRef? typeRef) => + typeRef is { Category: AtsTypeCategory.Handle }; + + /// + /// Maps an AtsTypeRef to a TypeScript type using category-based dispatch. + /// This is the preferred method - uses type metadata rather than string parsing. + /// + + internal string MapTypeRefToTypeScript(AtsTypeRef? typeRef) + { + if (typeRef is null) + { + return "unknown"; + } + + // ReferenceExpression is a value type defined in base.mts, not a handle-based wrapper + if (typeRef.TypeId == AtsConstants.ReferenceExpressionTypeId) + { + return GetReferenceExpressionInterfaceName(); + } + + if (typeRef.TypeId == InputTypeTypeId) + { + return GetInputTypeEnumName(); + } + + if (typeRef.TypeId == InteractionInputTypeId) + { + return GetInteractionInputInterfaceName(); + } + + if (typeRef.TypeId == InteractionInputCollectionTypeId) + { + return GetInteractionInputCollectionClassName(); + } + + // Check for wrapper class first (handles custom types like resource builders) + if (_wrapperClassNames.TryGetValue(typeRef.TypeId, out var wrapperClassName)) + { + return GetInterfaceName(wrapperClassName); + } + + var mappedType = typeRef.Category switch + { + AtsTypeCategory.Primitive => MapPrimitiveType(typeRef.TypeId), + AtsTypeCategory.Enum => MapEnumType(typeRef.TypeId), + AtsTypeCategory.Handle => GetWrapperOrHandleName(typeRef.TypeId), + AtsTypeCategory.Dto => GetDtoInterfaceName(typeRef.TypeId), + AtsTypeCategory.Callback => "Function", // Callbacks handled separately with full signature + AtsTypeCategory.Array => $"{MapTypeRefToTypeScript(typeRef.ElementType)}[]", + AtsTypeCategory.List => $"AspireList<{MapTypeRefToTypeScript(typeRef.ElementType)}>", + AtsTypeCategory.Dict => typeRef.IsReadOnly + ? $"Record<{MapTypeRefToTypeScript(typeRef.KeyType)}, {MapTypeRefToTypeScript(typeRef.ValueType)}>" + : $"AspireDict<{MapTypeRefToTypeScript(typeRef.KeyType)}, {MapTypeRefToTypeScript(typeRef.ValueType)}>", + AtsTypeCategory.Union => MapUnionTypeToTypeScript(typeRef), + AtsTypeCategory.Unknown => "any", // Unknown types use 'any' since they're not in the ATS universe + _ => "any" // Fallback for any unhandled categories + }; + return ApplyNullableType(typeRef, mappedType); + } + + internal static string ApplyNullableType(AtsTypeRef typeRef, string mappedType) + { + if (typeRef.IsNullable != true || typeRef.Category is not (AtsTypeCategory.Primitive or AtsTypeCategory.Enum)) + { + return mappedType; + } + + return typeRef.TypeId is AtsConstants.Void or AtsConstants.Any or AtsConstants.CancellationToken + ? mappedType + : $"{mappedType} | null"; + } + + internal string MapDtoPropertyTypeToTypeScript(AtsTypeRef? typeRef) + { + if (typeRef is null) + { + return "unknown"; + } + + return typeRef.Category switch + { + AtsTypeCategory.Array or AtsTypeCategory.List => $"{MapDtoPropertyTypeToTypeScript(typeRef.ElementType)}[]", + AtsTypeCategory.Dict => $"Record<{MapDtoPropertyTypeToTypeScript(typeRef.KeyType)}, {MapDtoPropertyTypeToTypeScript(typeRef.ValueType)}>", + AtsTypeCategory.Union => MapDtoUnionTypeToTypeScript(typeRef), + _ => MapTypeRefToTypeScript(typeRef) + }; + } + + internal string MapDtoUnionTypeToTypeScript(AtsTypeRef typeRef) + { + if (typeRef.UnionTypes is null || typeRef.UnionTypes.Count == 0) + { + return "unknown"; + } + + var memberTypes = typeRef.UnionTypes + .Select(MapDtoPropertyTypeToTypeScript) + .Distinct(); + + return string.Join(" | ", memberTypes); + } + + /// + /// Maps primitive type IDs to TypeScript types. + /// + + internal static string MapPrimitiveType(string typeId) => typeId switch + { + AtsConstants.String or AtsConstants.Char => "string", + AtsConstants.Number => "number", + AtsConstants.Boolean => "boolean", + AtsConstants.Void => "void", + AtsConstants.Any => "any", + AtsConstants.DateTime or AtsConstants.DateTimeOffset or + AtsConstants.DateOnly or AtsConstants.TimeOnly => "string", + AtsConstants.TimeSpan => "number", + AtsConstants.Guid or AtsConstants.Uri => "string", + AtsConstants.CancellationToken => GetCancellationTokenInterfaceName(), + _ => typeId + }; + + /// + /// Maps an enum type ID to the generated TypeScript enum name. + /// Throws if the enum type wasn't collected during scanning. + /// + + internal string MapEnumType(string typeId) + { + if (!_enumTypeNames.TryGetValue(typeId, out var enumName)) + { + throw new InvalidOperationException( + $"Enum type '{typeId}' was not found in the scanned enum types. " + + $"This indicates the enum type was not discovered during assembly scanning."); + } + return enumName; + } + + /// + /// Maps a union type to TypeScript union syntax (T1 | T2 | ...). + /// + + internal string MapUnionTypeToTypeScript(AtsTypeRef typeRef) + { + if (typeRef.UnionTypes == null || typeRef.UnionTypes.Count == 0) + { + return "unknown"; + } + + var memberTypes = typeRef.UnionTypes + .Select(MapTypeRefToTypeScript) + .Distinct(); + + return string.Join(" | ", memberTypes); + } + + /// + /// Gets the wrapper class name or handle type name for a handle type ID. + /// Prefers wrapper class if one exists, otherwise generates a handle type name. + /// + + internal string GetWrapperOrHandleName(string typeId) + { + if (_wrapperClassNames.TryGetValue(typeId, out var wrapperClassName)) + { + return wrapperClassName; + } + return GetHandleTypeName(typeId); + } + + /// + /// Gets a TypeScript interface name for a DTO type. + /// + + internal static string GetDtoInterfaceName(string typeId) + { + return ExtractSimpleTypeName(typeId); + } + + /// + /// Maps a user-supplied input type to TypeScript. + /// For interface handle types, generated APIs accept any handle-bearing wrapper instance. + /// For cancellation tokens, generated APIs accept either an AbortSignal or a transport-safe CancellationToken. + /// + /// + /// Handle types are widened to accept Awaitable<T> so callers can pass un-awaited + /// fluent chains directly. Examples: + /// + /// // Input: RedisResource handle type + /// // Output: "Awaitable<RedisResource>" + /// + /// // Input: Union of string | RedisResource + /// // Output: "string | Awaitable<RedisResource>" + /// + /// // Input: CancellationToken type + /// // Output: "AbortSignal | CancellationToken" + /// + /// // Input: plain string type + /// // Output: "string" + /// + /// + + internal string MapInputTypeToTypeScript(AtsTypeRef? typeRef) + { + if (typeRef?.Category == AtsTypeCategory.Union) + { + return MapInputUnionTypeToTypeScript(typeRef); + } + + if (IsInterfaceHandleType(typeRef)) + { + if (TryMapInterfaceInputTypeToTypeScript(typeRef!) is { } interfaceInputType) + { + return $"Awaitable<{interfaceInputType}>"; + } + + var handleName = GetHandleReferenceInterfaceName(); + return $"Awaitable<{handleName}>"; + } + + if (IsHandleType(typeRef) && _wrapperClassNames.TryGetValue(typeRef!.TypeId, out var className)) + { + var ifaceName = GetInterfaceName(className); + return $"Awaitable<{ifaceName}>"; + } + + if (typeRef?.TypeId == InteractionInputCollectionTypeId) + { + return $"Awaitable<{GetInteractionInputCollectionClassName()}>"; + } + + if (IsCancellationTokenType(typeRef)) + { + return $"AbortSignal | {GetCancellationTokenInterfaceName()}"; + } + + return MapTypeRefToTypeScript(typeRef); + } + + internal string MapInputUnionTypeToTypeScript(AtsTypeRef typeRef) + { + if (typeRef.UnionTypes == null || typeRef.UnionTypes.Count == 0) + { + throw new InvalidOperationException("Union input types must define at least one member type."); + } + + // Build union structurally: each member is mapped individually. + // Handle types become Awaitable, non-handle types pass through as-is. + var nonHandleTypes = new List(); + var handleTypeNames = new List(); + + foreach (var memberRef in typeRef.UnionTypes) + { + if (IsWidenedHandleType(memberRef)) + { + // Get the base type name without Awaitable wrapper for combining + var baseName = IsInterfaceHandleType(memberRef) && TryMapInterfaceInputTypeToTypeScript(memberRef) is { } expanded + ? expanded + : MapTypeRefToTypeScript(memberRef); + nonHandleTypes.Add(baseName); + handleTypeNames.Add(baseName); + } + else + { + nonHandleTypes.Add(MapInputTypeToTypeScript(memberRef)); + } + } + + var allBaseTypes = nonHandleTypes + .SelectMany(t => t.Split(" | ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)) + .Distinct(StringComparer.Ordinal) + .ToList(); + + if (handleTypeNames.Count > 0) + { + var handleUnion = string.Join(" | ", handleTypeNames + .SelectMany(t => t.Split(" | ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)) + .Distinct(StringComparer.Ordinal)); + return string.Join(" | ", allBaseTypes) + $" | Awaitable<{handleUnion}>"; + } + + return string.Join(" | ", allBaseTypes); + } + + /// + /// Maps a parameter to its TypeScript type, handling callbacks specially. + /// + + internal string MapParameterToTypeScript(AtsParameterInfo param) + { + if (param.IsCallback) + { + return GenerateCallbackTypeSignature(param.CallbackParameters, param.CallbackReturnType); + } + + return MapInputTypeToTypeScript(param.Type); + } + + internal string? TryMapInterfaceInputTypeToTypeScript(AtsTypeRef typeRef) + { + List? assignableWrapperTypes = null; + + foreach (var candidateTypeRef in _typeRefsById.Values) + { + if (!IsAssignableToInterface(candidateTypeRef, typeRef.TypeId) || + !_wrapperClassNames.TryGetValue(candidateTypeRef.TypeId, out var wrapperClassName)) + { + continue; + } + + assignableWrapperTypes ??= []; + assignableWrapperTypes.Add(wrapperClassName); + } + + if (assignableWrapperTypes is not { Count: > 0 }) + { + return null; + } + + return string.Join(" | ", assignableWrapperTypes + .Distinct(StringComparer.Ordinal) + .OrderBy(static n => n, StringComparer.Ordinal)); + } + + internal static bool IsAssignableToInterface(AtsTypeRef candidateTypeRef, string interfaceTypeId) + { + if (string.Equals(candidateTypeRef.TypeId, interfaceTypeId, StringComparison.Ordinal)) + { + return true; + } + + foreach (var implementedInterface in candidateTypeRef.ImplementedInterfaces) + { + if (IsAssignableToInterface(implementedInterface, interfaceTypeId)) + { + return true; + } + } + + return candidateTypeRef.BaseType is not null && IsAssignableToInterface(candidateTypeRef.BaseType, interfaceTypeId); + } + + /// + /// Checks if a type reference is an interface handle type. + /// Interface handles need union types to accept wrapper classes. + /// + + internal static bool IsInterfaceHandleType(AtsTypeRef? typeRef) + { + if (typeRef == null) + { + return false; + } + return typeRef.Category == AtsTypeCategory.Handle && typeRef.IsInterface; + } + + internal static bool IsCancellationTokenType(AtsTypeRef? typeRef) => typeRef?.TypeId == AtsConstants.CancellationToken; + + /// + /// Gets a valid TypeScript method name from a capability method name. + /// Handles dotted names like "EnvironmentContext.resource" by extracting just the final part. + /// + + internal static string GetTypeScriptMethodName(string methodName) + { + var dotIndex = methodName.LastIndexOf('.'); + return dotIndex >= 0 ? methodName[(dotIndex + 1)..] : methodName; + } + + /// + /// Converts a PascalCase name to camelCase. + /// + + internal static string ToCamelCase(string name) + { + if (string.IsNullOrEmpty(name)) + { + return name; + } + if (char.IsLower(name[0])) + { + return name; + } + return char.ToLowerInvariant(name[0]) + name[1..]; + } + + /// + /// Converts a camelCase name to PascalCase. + /// + + internal static string ToPascalCase(string name) + { + if (string.IsNullOrEmpty(name)) + { + return name; + } + if (char.IsUpper(name[0])) + { + return name; + } + return char.ToUpperInvariant(name[0]) + name[1..]; + } + + /// + /// Gets the options interface name for a method. + /// Strips any type prefix (e.g., "TypeName.methodName" -> "MethodName"). + /// + + internal static string GetOptionsInterfaceName(string methodName) + { + // Strip type prefix if present (e.g., "EndpointReference.getExpression" -> "getExpression") + var simpleName = methodName.Contains('.') + ? methodName[(methodName.LastIndexOf('.') + 1)..] + : methodName; + return $"{ToPascalCase(simpleName)}Options"; + } + + /// + /// Gets the options interface name for a specific capability, accounting for type conflicts. + /// Falls back to the default method-name-based interface if no specific mapping exists. + /// + + internal string ResolveOptionsInterfaceName(AtsCapabilityInfo capability) + { + if (_capabilityOptionsInterfaceMap.TryGetValue(capability.CapabilityId, out var interfaceName)) + { + return interfaceName; + } + return GetOptionsInterfaceName(capability.MethodName); + } + + /// + /// Separates parameters into required and optional lists. + /// Required = not optional and not nullable. + /// + + internal static (List Required, List Optional) SeparateParameters( + IEnumerable parameters) + { + var required = new List(); + var optional = new List(); + + foreach (var param in parameters) + { + if (param.IsOptional || param.IsNullable) + { + optional.Add(param); + } + else + { + required.Add(param); + } + } + + return (required, optional); + } + + internal static bool TryGetDirectOptionsParameter(List optionalParams, out AtsParameterInfo? directOptionsParam) + // A trailing cancellation token is rendered as its own parameter (see + // GetTrailingCancellationTokenParameter), so it is ignored when deciding whether the lone + // "options" DTO can be threaded directly instead of wrapped in a generated options object. + => AtsOptionsFlattening.TryGetDirectOptionsParameter( + optionalParams, + p => IsCancellationTokenType(p.Type), + cancellationTokenIsSeparateParameter: true, + out directOptionsParam); + + /// + /// When the options DTO is threaded directly (see ), + /// returns the trailing cancellation token optional parameter (if any) so it can be appended to + /// the generated method as its own argument rather than being folded into a generated options bag. + /// + + internal static AtsParameterInfo? GetTrailingCancellationTokenParameter(List optionalParams) + { + if (!TryGetDirectOptionsParameter(optionalParams, out _)) + { + return null; + } + + return optionalParams.FirstOrDefault(p => IsCancellationTokenType(p.Type)); + } + + /// + /// Registers an options interface to be generated later. + /// Uses method name to create the interface name. When methods share a name but have + /// incompatible callback parameter types, separate options interfaces are created with + /// numeric suffixes (e.g., RunAsEmulatorOptions, RunAsEmulator1Options). + /// + + internal void RegisterOptionsInterface(string capabilityId, string methodName, List optionalParams) + { + if (optionalParams.Count == 0) + { + return; + } + + var baseInterfaceName = GetOptionsInterfaceName(methodName); + + // Check if an existing interface with this name is compatible + if (_optionsInterfacesToGenerate.TryGetValue(baseInterfaceName, out var existingParams)) + { + if (AreOptionsCompatible(existingParams, optionalParams)) + { + // Compatible - merge any new parameters and share the interface + var existingNames = new HashSet(existingParams.Select(p => p.Name)); + foreach (var param in optionalParams) + { + if (existingNames.Add(param.Name)) + { + existingParams.Add(param); + } + } + _capabilityOptionsInterfaceMap[capabilityId] = baseInterfaceName; + return; + } + + // Incompatible - find or create a suffixed interface + for (var suffix = 1; ; suffix++) + { + var suffixedName = GetOptionsInterfaceName($"{methodName}{suffix}"); + if (!_optionsInterfacesToGenerate.TryGetValue(suffixedName, out var suffixedParams)) + { + // Create a new interface with this suffix + _generatedOptionsInterfaces.Add(suffixedName); + _optionsInterfacesToGenerate[suffixedName] = [.. optionalParams]; + _capabilityOptionsInterfaceMap[capabilityId] = suffixedName; + return; + } + + if (AreOptionsCompatible(suffixedParams, optionalParams)) + { + // Compatible with this suffixed interface - share it + var existingNames2 = new HashSet(suffixedParams.Select(p => p.Name)); + foreach (var param in optionalParams) + { + if (existingNames2.Add(param.Name)) + { + suffixedParams.Add(param); + } + } + _capabilityOptionsInterfaceMap[capabilityId] = suffixedName; + return; + } + } + } + else + { + // First registration - create the interface + _generatedOptionsInterfaces.Add(baseInterfaceName); + _optionsInterfacesToGenerate[baseInterfaceName] = [.. optionalParams]; + _capabilityOptionsInterfaceMap[capabilityId] = baseInterfaceName; + } + } + + /// + /// Checks whether two sets of optional parameters are compatible for sharing an options interface. + /// Parameters with the same name must have the same type (including callback parameter types). + /// + + internal static bool AreOptionsCompatible(List existing, List candidate) + { + foreach (var param in candidate) + { + var match = existing.FirstOrDefault(p => p.Name == param.Name); + if (match is null) + { + continue; // New parameter, no conflict + } + + // Same name - check type compatibility + if (!AreParameterTypesEqual(match, param)) + { + return false; + } + } + return true; + } + + /// + /// Checks whether two parameter infos have the same type (including callback types). + /// + + internal static bool AreParameterTypesEqual(AtsParameterInfo a, AtsParameterInfo b) + { + // Compare base type + var aTypeId = a.Type?.TypeId; + var bTypeId = b.Type?.TypeId; + if (!string.Equals(aTypeId, bTypeId, StringComparison.Ordinal)) + { + return false; + } + + // Compare callback parameter types + if (a.IsCallback != b.IsCallback) + { + return false; + } + + if (a.IsCallback && b.IsCallback) + { + var aCallbackParams = a.CallbackParameters ?? []; + var bCallbackParams = b.CallbackParameters ?? []; + + if (aCallbackParams.Count != bCallbackParams.Count) + { + return false; + } + + for (var i = 0; i < aCallbackParams.Count; i++) + { + if (!string.Equals(aCallbackParams[i].Type.TypeId, bCallbackParams[i].Type.TypeId, StringComparison.Ordinal)) + { + return false; + } + } + + // Compare callback return types + var aReturnTypeId = a.CallbackReturnType?.TypeId; + var bReturnTypeId = b.CallbackReturnType?.TypeId; + if (!string.Equals(aReturnTypeId, bReturnTypeId, StringComparison.Ordinal)) + { + return false; + } + } + + return true; + } + + internal static string GetTypeDescription(string typeId) + { + var typeName = ExtractSimpleTypeName(typeId); + return $"Handle to {typeName}"; + } + + internal string BuildPublicParameterList( + List requiredParams, + bool hasOptionals, + string optionsInterfaceName, + string optionsParameterName = "options", + AtsParameterInfo? trailingCancellationToken = null) + { + var publicParamDefs = new List(); + foreach (var param in requiredParams) + { + var tsType = MapParameterToTypeScript(param); + publicParamDefs.Add($"{param.Name}: {tsType}"); + } + if (hasOptionals) + { + publicParamDefs.Add($"{optionsParameterName}?: {optionsInterfaceName}"); + } + if (trailingCancellationToken is not null) + { + publicParamDefs.Add($"{trailingCancellationToken.Name}?: {MapParameterToTypeScript(trailingCancellationToken)}"); + } + + return string.Join(", ", publicParamDefs); + } + + internal static string GetPublicOptionsParameterName( + IReadOnlyList userParams, + bool hasOptionals, + bool hasDirectOptionsParameter) + { + if (!hasOptionals || hasDirectOptionsParameter) + { + return "options"; + } + + if (!userParams.Any(p => string.Equals(p.Name, "options", StringComparison.Ordinal))) + { + return "options"; + } + + var candidate = "optionsBag"; + while (userParams.Any(p => string.Equals(p.Name, candidate, StringComparison.Ordinal))) + { + candidate = $"_{candidate}"; + } + + return candidate; + } + + internal static bool IsGetterOnlyProperty(AtsCapabilityInfo? getter, AtsCapabilityInfo? setter) => getter is not null && setter is null; + + internal string GetGetterOnlyPropertyReturnType(AtsTypeRef? typeRef) + { + if (typeRef == null) + { + return "unknown"; + } + + if (IsDictionaryType(typeRef)) + { + var keyType = typeRef.KeyType != null ? MapTypeRefToTypeScript(typeRef.KeyType) : "string"; + var valueType = typeRef.ValueType != null ? MapTypeRefToTypeScript(typeRef.ValueType) : "unknown"; + return $"AspireDict<{keyType}, {valueType}>"; + } + + if (IsListType(typeRef)) + { + var elementType = typeRef.ElementType != null ? MapTypeRefToTypeScript(typeRef.ElementType) : "unknown"; + return $"AspireList<{elementType}>"; + } + + return MapTypeRefToTypeScript(typeRef); + } + + internal bool TryGetPromiseWrapperType(AtsTypeRef? typeRef, out string promiseInterfaceName, out string promiseImplementationClassName) + { + if (typeRef?.TypeId is { } typeId && _typesWithPromiseWrappers.Contains(typeId)) + { + var className = GetConcreteClassName(typeId); + promiseInterfaceName = GetPromiseInterfaceName(className); + promiseImplementationClassName = GetImplementationPromiseClassName(className); + return true; + } + + promiseInterfaceName = string.Empty; + promiseImplementationClassName = string.Empty; + return false; + } + + internal string GetGetterOnlyPropertyMethodReturnType(AtsTypeRef? typeRef) + { + if (TryGetPromiseWrapperType(typeRef, out var promiseInterfaceName, out _)) + { + return promiseInterfaceName; + } + + return $"Promise<{GetGetterOnlyPropertyReturnType(typeRef)}>"; + } + + internal string GetBuilderPromiseInterfaceForMethod(BuilderModel builder, AtsCapabilityInfo capability) + { + if (capability.ReturnsBuilder && capability.ReturnType?.TypeId != null && + !string.Equals(capability.ReturnType.TypeId, builder.TypeId, StringComparison.Ordinal) && + !string.Equals(capability.ReturnType.TypeId, capability.TargetTypeId, StringComparison.Ordinal)) + { + return GetPublicPromiseInterfaceName(capability.ReturnType.TypeId); + } + + return GetPromiseInterfaceName(builder.BuilderClassName); + } + + /// + /// Checks if a type was widened to accept Awaitable<T> in input position. + /// Must match the widening logic in MapInputTypeToTypeScript exactly. + /// + + internal bool IsWidenedHandleType(AtsTypeRef? typeRef) + { + if (typeRef == null) + { + return false; + } + + // Interface handles are always widened + if (IsInterfaceHandleType(typeRef)) + { + return true; + } + + // Concrete handles are only widened if they have a wrapper class name + // (excludes special types like ReferenceExpression that bypass widening) + if (IsHandleType(typeRef) && _wrapperClassNames.ContainsKey(typeRef.TypeId)) + { + return true; + } + + if (typeRef.TypeId == InteractionInputCollectionTypeId) + { + return true; + } + + if (typeRef.Category == AtsTypeCategory.Union && typeRef.UnionTypes is { Count: > 0 }) + { + return typeRef.UnionTypes.Any(IsWidenedHandleType); + } + + return false; + } + + /// + /// Groups getters and setters by property name. + /// + + internal static List<(string PropertyName, AtsCapabilityInfo? Getter, AtsCapabilityInfo? Setter)> GroupPropertiesByName( + List getters, List setters) + { + var result = new List<(string PropertyName, AtsCapabilityInfo? Getter, AtsCapabilityInfo? Setter)>(); + var processedNames = new HashSet(); + + // Process getters + foreach (var getter in getters) + { + var propName = ExtractPropertyName(getter.MethodName); + if (processedNames.Contains(propName)) + { + continue; + } + processedNames.Add(propName); + + // Find matching setter (setPropertyName for propertyName) + var setterName = "set" + char.ToUpperInvariant(propName[0]) + propName[1..]; + var setter = setters.FirstOrDefault(s => ExtractPropertyName(s.MethodName).Equals(setterName, StringComparison.OrdinalIgnoreCase)); + + result.Add((propName, getter, setter)); + } + + // Process any setters without matching getters + foreach (var setter in setters) + { + var setterMethodName = ExtractPropertyName(setter.MethodName); + // setPropertyName -> propertyName + if (setterMethodName.StartsWith("set", StringComparison.OrdinalIgnoreCase) && setterMethodName.Length > 3) + { + var propName = char.ToLowerInvariant(setterMethodName[3]) + setterMethodName[4..]; + if (!processedNames.Contains(propName)) + { + processedNames.Add(propName); + result.Add((propName, null, setter)); + } + } + } + + return result; + } + + /// + /// Extracts the property name from a method name like "ClassName.propertyName" or "setPropertyName". + /// + + internal static string ExtractPropertyName(string methodName) + { + // Handle "ClassName.propertyName" format + if (methodName.Contains('.')) + { + return methodName[(methodName.LastIndexOf('.') + 1)..]; + } + return methodName; + } + + /// + /// Checks if a type reference is a dictionary type. + /// + + internal static bool IsDictionaryType(AtsTypeRef? typeRef) + { + return typeRef?.Category == AtsTypeCategory.Dict; + } + + /// + /// Checks if a type reference is a list type. + /// + + internal static bool IsListType(AtsTypeRef? typeRef) + { + return typeRef?.Category == AtsTypeCategory.List; + } + + /// + /// Groups capabilities by ExpandedTargetTypes to create builder models. + /// Uses expansion to map interface targets to their concrete implementations. + /// Also creates builders for interface types (for use as return type wrappers). + /// + + internal static List CreateBuilderModels(IReadOnlyList capabilities) + { + // Group capabilities by expanded target type IDs + // A capability targeting IResource with ExpandedTargetTypes = [RedisResource] + // will be assigned to Aspire.Hosting.Redis/RedisResource (the concrete type) + var capabilitiesByTypeId = new Dictionary>(); + + // Track the AtsTypeRef for each typeId (from ExpandedTargetTypes or TargetType metadata) + var typeRefsByTypeId = new Dictionary(); + + // Also track interface types and their capabilities (for interface wrapper classes) + var interfaceCapabilities = new Dictionary>(); + + foreach (var cap in capabilities) + { + var targetTypeRef = cap.TargetType; + var targetTypeId = cap.TargetTypeId; + if (targetTypeRef == null || string.IsNullOrEmpty(targetTypeId)) + { + // Entry point methods - handled separately + continue; + } + + // Use category-based check instead of string parsing + if (targetTypeRef.Category != AtsTypeCategory.Handle) + { + continue; + } + + // These types are implemented manually in base.mts, including handle wrapper + // registrations, so they must not also generate duplicate wrappers in aspire.mts. + if (targetTypeId is AtsConstants.ReferenceExpressionTypeId or InteractionInputCollectionTypeId) + { + continue; + } + + // Use expanded types if available, otherwise fall back to the original target + var expandedTypes = cap.ExpandedTargetTypes; + if (expandedTypes is { Count: > 0 }) + { + // Flatten to concrete types + foreach (var expandedType in expandedTypes) + { + if (!capabilitiesByTypeId.TryGetValue(expandedType.TypeId, out var list)) + { + list = []; + capabilitiesByTypeId[expandedType.TypeId] = list; + // Store the type ref for this expanded type + typeRefsByTypeId[expandedType.TypeId] = expandedType; + } + list.Add(cap); + } + + // Also track the original interface type for wrapper class generation + if (targetTypeRef.IsInterface) + { + if (!interfaceCapabilities.TryGetValue(targetTypeId, out var interfaceList)) + { + interfaceList = []; + interfaceCapabilities[targetTypeId] = interfaceList; + // Store the type ref for the interface + typeRefsByTypeId[targetTypeId] = targetTypeRef; + } + interfaceList.Add(cap); + } + } + else + { + // No expansion - use original target (concrete type) + if (!capabilitiesByTypeId.TryGetValue(targetTypeId, out var list)) + { + list = []; + capabilitiesByTypeId[targetTypeId] = list; + // Store the type ref for this target type + typeRefsByTypeId[targetTypeId] = targetTypeRef; + } + list.Add(cap); + } + } + + // Create a builder for each concrete type with its specific capabilities + var builders = new List(); + foreach (var (typeId, typeCapabilities) in capabilitiesByTypeId) + { + var builderClassName = DeriveClassName(typeId); + + // Get the type ref from tracked metadata (based on target type, not return type) + var typeRef = typeRefsByTypeId.GetValueOrDefault(typeId); + + // Deduplicate capabilities by CapabilityId to avoid duplicate methods + var uniqueCapabilities = typeCapabilities + .GroupBy(c => c.CapabilityId) + .Select(g => g.First()) + .ToList(); + + var builder = new BuilderModel + { + TypeId = typeId, + BuilderClassName = builderClassName, + Capabilities = uniqueCapabilities, + IsInterface = typeRef?.IsInterface ?? false, + TargetType = typeRef + }; + + builders.Add(builder); + } + + // Also create builders for interface types (for use as return type wrappers) + // These are needed when methods return interface types like IResourceWithConnectionString + foreach (var (interfaceTypeId, caps) in interfaceCapabilities) + { + // Skip if already added (shouldn't happen, but be safe) + if (capabilitiesByTypeId.ContainsKey(interfaceTypeId)) + { + continue; + } + + var builderClassName = DeriveClassName(interfaceTypeId); + + // Get the type ref from tracked metadata + var typeRef = typeRefsByTypeId.GetValueOrDefault(interfaceTypeId); + + // Deduplicate capabilities + var uniqueCapabilities = caps + .GroupBy(c => c.CapabilityId) + .Select(g => g.First()) + .ToList(); + + var builder = new BuilderModel + { + TypeId = interfaceTypeId, + BuilderClassName = builderClassName, + Capabilities = uniqueCapabilities, + IsInterface = true, + TargetType = typeRef + }; + + builders.Add(builder); + } + + // Also create builders for resource types referenced anywhere in capabilities + // This handles types like RedisCommanderResource that appear in callback signatures, + // return types, or parameter types but aren't capability targets + var allReferencedTypeRefs = CollectAllReferencedTypes(capabilities); + + // Track all types we already have builders for (concrete + interface) + var existingBuilderTypeIds = new HashSet(capabilitiesByTypeId.Keys); + foreach (var (interfaceTypeId, _) in interfaceCapabilities) + { + existingBuilderTypeIds.Add(interfaceTypeId); + } + + foreach (var (typeId, typeRef) in allReferencedTypeRefs) + { + // Skip types we already have builders for (from concrete or interface lists) + if (existingBuilderTypeIds.Contains(typeId)) + { + continue; + } + + // Only create builders for resource types (using metadata instead of string parsing) + if (!typeRef.IsResourceBuilder) + { + continue; + } + + var builderClassName = DeriveClassName(typeId); + var builder = new BuilderModel + { + TypeId = typeId, + BuilderClassName = builderClassName, + Capabilities = [], // No specific capabilities - uses base type methods + IsInterface = typeRef.IsInterface, + TargetType = typeRef + }; + builders.Add(builder); + } + + // Deduplicate builders by class name, preferring concrete types over interfaces. + // This handles cases where both a concrete type (e.g. AzureKeyVaultResource) and + // its interface (IAzureKeyVaultResource → AzureKeyVaultResource) produce the same class name. + // Sort: concrete types first, then interfaces + return builders + .OrderBy(b => b.IsInterface) + .ThenBy(b => b.BuilderClassName) + .GroupBy(b => b.BuilderClassName) + .Select(g => g.First()) + .ToList(); + } + + /// + /// Collects all type refs referenced in capabilities (return types, parameter types, callback types, etc.) + /// Returns a dictionary mapping typeId to AtsTypeRef for use in builder creation. + /// + + internal static Dictionary CollectAllReferencedTypes(IReadOnlyList capabilities) + { + var typeRefs = new Dictionary(); + + void CollectFromTypeRef(AtsTypeRef? typeRef) + { + if (typeRef == null) + { + return; + } + + if (!string.IsNullOrEmpty(typeRef.TypeId) && typeRef.Category == AtsTypeCategory.Handle) + { + typeRefs.TryAdd(typeRef.TypeId, typeRef); + } + + // Also check nested types (generics, arrays, etc.) + CollectFromTypeRef(typeRef.ElementType); + CollectFromTypeRef(typeRef.KeyType); + CollectFromTypeRef(typeRef.ValueType); + if (typeRef.UnionTypes != null) + { + foreach (var unionType in typeRef.UnionTypes) + { + CollectFromTypeRef(unionType); + } + } + } + + foreach (var cap in capabilities) + { + // Check return type + CollectFromTypeRef(cap.ReturnType); + + // Check parameter types + foreach (var param in cap.Parameters) + { + CollectFromTypeRef(param.Type); + + // Check callback parameter types and return type + if (param.IsCallback) + { + if (param.CallbackParameters != null) + { + foreach (var cbParam in param.CallbackParameters) + { + CollectFromTypeRef(cbParam.Type); + } + } + CollectFromTypeRef(param.CallbackReturnType); + } + } + } + + return typeRefs; + } + + /// + /// Gets entry point capabilities (those without TargetTypeId). + /// + + internal static List GetEntryPointCapabilities(IReadOnlyList capabilities) + { + return capabilities.Where(c => string.IsNullOrEmpty(c.TargetTypeId)).ToList(); + } + + /// + /// Derives the class name from an ATS type ID. + /// For interfaces like IResource, strips the leading 'I'. + /// + + internal static string DeriveClassName(string typeId) + { + var typeName = ExtractSimpleTypeName(typeId); + + // Strip leading 'I' from interface types + if (typeName.StartsWith('I') && typeName.Length > 1 && char.IsUpper(typeName[1])) + { + return typeName[1..]; + } + + return typeName; + } + + /// + /// Gets the handle type alias name for a type ID. + /// + + internal static string GetHandleTypeName(string typeId) + { + var typeName = ExtractSimpleTypeName(typeId); + + // Sanitize generic types like "Dict" -> "DictStringObject" + // and array types like "string[]" -> "stringArray" + typeName = typeName + .Replace("[]", "Array", StringComparison.Ordinal) + .Replace("<", "", StringComparison.Ordinal) + .Replace(">", "", StringComparison.Ordinal) + .Replace(",", "", StringComparison.Ordinal); + + return $"{typeName}Handle"; + } + + /// + /// Extracts the simple type name from a type ID. + /// + /// + /// "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource" → "IResource" + /// "Aspire.Hosting/Aspire.Hosting.DistributedApplication" → "DistributedApplication" + /// + + internal static string ExtractSimpleTypeName(string typeId) + { + var slashIndex = typeId.LastIndexOf('/'); + var fullTypeName = slashIndex >= 0 ? typeId[(slashIndex + 1)..] : typeId; + + var dotIndex = fullTypeName.LastIndexOf('.'); + return dotIndex >= 0 ? fullTypeName[(dotIndex + 1)..] : fullTypeName; + } + + /// + /// Determines if a type has generated async members and should have a Promise wrapper. + /// Types with instance methods, wrapper methods, or getter-only properties get Promise wrappers. + /// + + internal static bool HasChainableMethods(BuilderModel model) + { + var hasMethods = model.Capabilities.Any(c => + c.CapabilityKind == AtsCapabilityKind.InstanceMethod || + c.CapabilityKind == AtsCapabilityKind.Method); + if (hasMethods) + { + return true; + } + + var getters = model.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); + var setters = model.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); + + return GroupPropertiesByName(getters, setters).Any(p => IsGetterOnlyProperty(p.Getter, p.Setter)); + } + + /// + /// Gets the Promise wrapper class name for a return type, if one exists. + /// Returns null if the return type doesn't have a Promise wrapper. + /// + + internal string? GetPromiseWrapperForReturnType(AtsTypeRef? returnType) + { + if (returnType == null) + { + return null; + } + + // Check if the return type has a Promise wrapper + if (_typesWithPromiseWrappers.Contains(returnType.TypeId)) + { + var className = _wrapperClassNames.GetValueOrDefault(returnType.TypeId) + ?? DeriveClassName(returnType.TypeId); + return $"{className}Promise"; + } + + return null; + } + + internal string GenerateCallbackTypeSignature(IReadOnlyList? callbackParameters, AtsTypeRef? callbackReturnType) + { + // Build parameter list + var paramList = new List(); + if (callbackParameters is not null) + { + foreach (var param in callbackParameters) + { + var tsType = MapTypeRefToTypeScript(param.Type); + paramList.Add($"{param.Name}: {tsType}"); + } + } + + var paramsString = paramList.Count > 0 ? string.Join(", ", paramList) : ""; + + // Determine return type + var returnType = callbackReturnType == null || callbackReturnType.TypeId == AtsConstants.Void + ? "void" + : MapTypeRefToTypeScript(callbackReturnType); + + // Callbacks are always async in TypeScript + return $"({paramsString}) => Promise<{returnType}>"; + } +} diff --git a/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj b/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj index 3f7178b5e4d..fc558519503 100644 --- a/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj +++ b/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj @@ -22,6 +22,10 @@ + + diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 780e8abd4ea..bdebf11ab46 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -4,6 +4,7 @@ #pragma warning disable ASPIREBROWSERLOGS001 // Type is for evaluation purposes only using System.Reflection; +using System.Text.RegularExpressions; using Aspire.Hosting.Azure; using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.RemoteHost; @@ -776,8 +777,7 @@ public void AspireUnion_InterfaceHandleInput_GeneratesExpandedUnion() [Fact] public void MapInputUnionTypeToTypeScript_ThrowsOnEmptyUnion() { - var method = typeof(AtsTypeScriptCodeGenerator).GetMethod("MapInputUnionTypeToTypeScript", BindingFlags.Instance | BindingFlags.NonPublic); - Assert.NotNull(method); + var projector = new TypeScriptApiProjector(CreateContextFromTestAssembly()); var typeRef = new AtsTypeRef { @@ -786,9 +786,8 @@ public void MapInputUnionTypeToTypeScript_ThrowsOnEmptyUnion() UnionTypes = [], }; - var ex = Assert.Throws(() => method.Invoke(_generator, [typeRef])); - Assert.IsType(ex.InnerException); - Assert.Equal("Union input types must define at least one member type.", ex.InnerException.Message); + var ex = Assert.Throws(() => projector.MapInputUnionTypeToTypeScript(typeRef)); + Assert.Equal("Union input types must define at least one member type.", ex.Message); } [Fact] @@ -1884,4 +1883,210 @@ public void Scanner_PackageManagerMethods_ExpandToAllJavaScriptResourceTypes(str Assert.Contains(expandedTypeIds, id => id.Contains(nameof(JavaScript.NodeAppResource), StringComparison.Ordinal)); Assert.Contains(expandedTypeIds, id => id.Contains(nameof(JavaScript.ViteAppResource), StringComparison.Ordinal)); } + + // ===== Canonical API export ===== + // + // The canonical export is the contract aspire.dev consumes to render TypeScript API + // documentation. It must be produced from the same resolved projection the source + // emitter uses, because documentation that reconstructs signatures from raw ATS + // drifts from the SDK that actually ships (microsoft/aspire#17608). + + /// + /// The exporting package for the canonical export tests. The test assembly owns the + /// documented symbols; Aspire.Hosting contributes referenced types through the closure. + /// + private const string TestPackageName = "Aspire.Hosting.CodeGeneration.TypeScript.Tests"; + + private const string TestPackageVersion = "13.5.0"; + + [Fact] + public async Task ApiExportUsesTheSameResolvedSignaturesAsGeneratedSource() + { + var atsContext = CreateOwnershipFilteredContext(); + + var projector = new TypeScriptApiProjector(atsContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var exportJson = TypeScriptApiExportWriter.WriteToJson(model, indented: true); + + await Verify(exportJson, extension: "json") + .UseFileName("AtsTypeScriptCodeGeneratorTests.ApiExport"); + + // Declaration fragments are snapshotted separately: aspire.dev concatenates them in + // stable-ID order and type-checks the result, so their exact text is a contract. + var declarations = string.Join( + "\n\n", + model.Declarations.Select(declaration => $"// {declaration.Id}\n{declaration.Content}")); + + await Verify(declarations, extension: "txt") + .UseFileName("AtsTypeScriptCodeGeneratorTests.ApiDeclarations"); + } + + [Fact] + public void ApiExportDeclarationsAppearInGeneratedPublicInterfaces() + { + var atsContext = CreateOwnershipFilteredContext(); + + var projector = new TypeScriptApiProjector(atsContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(atsContext)["aspire.mts"]; + + // Keep this assertion narrow. It proves both emitters consume the same resolved + // projection without snapshotting all runtime implementation code: every method + // signature the export publishes must be present verbatim in the generated public + // interface for the type that owns it. + var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); + + var checkedDeclarations = 0; + foreach (var module in model.Modules) + { + foreach (var item in module.Items) + { + foreach (var member in item.Members.Where(m => m.Kind == TypeScriptApiItemKind.Method)) + { + Assert.True( + generatedInterfaceMembers.TryGetValue(item.Name, out var members), + $"Exported type '{item.Name}' has no generated public interface."); + + Assert.True( + members.Contains(member.Declaration), + $"Exported declaration '{member.Declaration}' on '{item.Name}' does not appear in the generated public interface. " + + $"Generated members: {string.Join(", ", members)}"); + + checkedDeclarations++; + } + } + } + + Assert.True(checkedDeclarations > 0, "The canonical export produced no method declarations to compare."); + } + + [Fact] + public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() + { + var atsContext = CreateOwnershipFilteredContext(); + + var projector = new TypeScriptApiProjector(atsContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var documentedItems = model.Modules.SelectMany(module => module.Items).ToList(); + + // Every documented item must be something this package published: either it owns the type, + // or it contributes members to a type another package owns. Anything else would republish + // another package's surface under this package's version. + Assert.All(documentedItems, item => + Assert.True( + item.TypeId.StartsWith($"{TestPackageName}/", StringComparison.Ordinal) || + item.OwningAssemblyName == TestPackageName, + $"Item '{item.Id}' ({item.TypeId}) is neither package-owned nor a package contribution.")); + + // Members are owned per capability, so no documented member may come from another assembly. + Assert.All( + documentedItems.SelectMany(item => item.Members), + member => Assert.Equal(TestPackageName, member.OwningAssemblyName)); + + // The closure must reach types this package does not own; otherwise the fixture would not + // exercise cross-package references at all. + var referencedTypeIds = atsContext.HandleTypes + .Select(type => type.AtsTypeId) + .Where(typeId => !typeId.StartsWith($"{TestPackageName}/", StringComparison.Ordinal)) + .ToList(); + + Assert.NotEmpty(referencedTypeIds); + + var declarationIds = model.Declarations.Select(declaration => declaration.Id).ToList(); + Assert.Equal(declarationIds.Count, declarationIds.Distinct(StringComparer.Ordinal).Count()); + + // Referenced types must reach the declaration fragments under their real owner, otherwise + // the concatenated declarations would not type-check. + Assert.Contains(model.Declarations, declaration => declaration.OwningAssemblyName == "Aspire.Hosting"); + + // Every type name the declarations reference must also be declared by the declarations. + var declaredNames = model.Declarations + .SelectMany(declaration => Regex.Matches(declaration.Content, @"export (?:interface|enum|type) (\w+)")) + .Select(match => match.Groups[1].Value) + .ToHashSet(StringComparer.Ordinal); + + Assert.Contains("ResourceBuilderBase", declaredNames); + Assert.Contains("ContainerResource", declaredNames); + } + + /// + /// Builds the context the canonical exporter sees for a single package: the package's own + /// capabilities plus the transitive closure of types they reference from other assemblies. + /// This mirrors what RemoteHost passes to the exporter for one Name@Version request. + /// + private static AtsContext CreateOwnershipFilteredContext() + { + return AtsContextFilter.FilterByExportingAssembliesWithReferences( + CreateContextFromBothAssemblies(), + [TestPackageName]); + } + + /// + /// Extracts the member signature lines of every generated export interface block. + /// + /// + /// The generated source declares public surface as interfaces, for example: + /// + /// export interface TestRedisResourceBuilder extends ResourceBuilderBase { + /// /** doc comment */ + /// withPersistence(options?: WithPersistenceOptions): TestRedisResourceBuilderPromise; + /// } + /// + /// Only lines that terminate with ; at brace depth 1 are member signatures; doc + /// comments, blank lines, and nested object literals are skipped. Signatures are stored + /// without the trailing semicolon so they compare directly against exported declarations. + /// + private static Dictionary> ParsePublicInterfaceMembers(string generatedSource) + { + var membersByInterface = new Dictionary>(StringComparer.Ordinal); + + string? currentInterface = null; + var depth = 0; + + foreach (var rawLine in generatedSource.Split('\n')) + { + var line = rawLine.Trim(); + + if (currentInterface is null) + { + // Matches "export interface Name {" and "export interface Name extends Base {". + if (!line.StartsWith("export interface ", StringComparison.Ordinal) || !line.EndsWith('{')) + { + continue; + } + + var header = line["export interface ".Length..^1].Trim(); + var extendsIndex = header.IndexOf(" extends ", StringComparison.Ordinal); + currentInterface = (extendsIndex >= 0 ? header[..extendsIndex] : header).Trim(); + membersByInterface.TryAdd(currentInterface, new HashSet(StringComparer.Ordinal)); + depth = 1; + continue; + } + + depth += line.Count(c => c == '{') - line.Count(c => c == '}'); + + if (depth <= 0) + { + currentInterface = null; + continue; + } + + if (depth == 1 && line.EndsWith(';') && !line.StartsWith('*') && !line.StartsWith("//", StringComparison.Ordinal)) + { + membersByInterface[currentInterface].Add(line[..^1].Trim()); + } + } + + return membersByInterface; + } } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt new file mode 100644 index 00000000000..64715c97594 --- /dev/null +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -0,0 +1,951 @@ +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource +export interface CSharpAppResource { + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; + withConfig(config: TestConfigDto): CSharpAppResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; + withCreatedAt(createdAt: string): CSharpAppResourcePromise; + withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; + withCorrelationId(correlationId: string): CSharpAppResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; + withStatus(status: TestResourceStatus): CSharpAppResourcePromise; + withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; + testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; + withDependency(dependency: Awaitable): CSharpAppResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): CSharpAppResourcePromise; + withEndpoints(endpoints: string[]): CSharpAppResourcePromise; + withEnvironmentVariables(variables: Record): CSharpAppResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): CSharpAppResourcePromise; + withMergeLabel(label: string): CSharpAppResourcePromise; + withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; + withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise +export interface CSharpAppResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; + withConfig(config: TestConfigDto): CSharpAppResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; + withCreatedAt(createdAt: string): CSharpAppResourcePromise; + withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; + withCorrelationId(correlationId: string): CSharpAppResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; + withStatus(status: TestResourceStatus): CSharpAppResourcePromise; + withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; + testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; + withDependency(dependency: Awaitable): CSharpAppResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): CSharpAppResourcePromise; + withEndpoints(endpoints: string[]): CSharpAppResourcePromise; + withEnvironmentVariables(variables: Record): CSharpAppResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): CSharpAppResourcePromise; + withMergeLabel(label: string): CSharpAppResourcePromise; + withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; + withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource +export interface ContainerRegistryResource { + withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; + withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; + withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; + withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; + withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; + withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; + testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; + withDependency(dependency: Awaitable): ContainerRegistryResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerRegistryResourcePromise; + withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerRegistryResourcePromise; + withMergeLabel(label: string): ContainerRegistryResourcePromise; + withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise +export interface ContainerRegistryResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; + withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; + withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; + withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; + withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; + withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; + testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; + withDependency(dependency: Awaitable): ContainerRegistryResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerRegistryResourcePromise; + withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerRegistryResourcePromise; + withMergeLabel(label: string): ContainerRegistryResourcePromise; + withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource +export interface ContainerResource { + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; + withConfig(config: TestConfigDto): ContainerResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; + withCreatedAt(createdAt: string): ContainerResourcePromise; + withModifiedAt(modifiedAt: string): ContainerResourcePromise; + withCorrelationId(correlationId: string): ContainerResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; + withStatus(status: TestResourceStatus): ContainerResourcePromise; + withNestedConfig(config: TestNestedDto): ContainerResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; + testWaitFor(dependency: Awaitable): ContainerResourcePromise; + withDependency(dependency: Awaitable): ContainerResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerResourcePromise; + withEndpoints(endpoints: string[]): ContainerResourcePromise; + withEnvironmentVariables(variables: Record): ContainerResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerResourcePromise; + withMergeLabel(label: string): ContainerResourcePromise; + withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise +export interface ContainerResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; + withConfig(config: TestConfigDto): ContainerResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; + withCreatedAt(createdAt: string): ContainerResourcePromise; + withModifiedAt(modifiedAt: string): ContainerResourcePromise; + withCorrelationId(correlationId: string): ContainerResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; + withStatus(status: TestResourceStatus): ContainerResourcePromise; + withNestedConfig(config: TestNestedDto): ContainerResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; + testWaitFor(dependency: Awaitable): ContainerResourcePromise; + withDependency(dependency: Awaitable): ContainerResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerResourcePromise; + withEndpoints(endpoints: string[]): ContainerResourcePromise; + withEnvironmentVariables(variables: Record): ContainerResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerResourcePromise; + withMergeLabel(label: string): ContainerResourcePromise; + withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder +export interface DistributedApplicationBuilder { + addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; + addTestVault(name: string): TestVaultResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise +export interface DistributedApplicationBuilderPromise { + addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; + addTestVault(name: string): TestVaultResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource +export interface DotnetToolResource { + withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; + withConfig(config: TestConfigDto): DotnetToolResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; + withCreatedAt(createdAt: string): DotnetToolResourcePromise; + withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; + withCorrelationId(correlationId: string): DotnetToolResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; + withStatus(status: TestResourceStatus): DotnetToolResourcePromise; + withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; + testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; + withDependency(dependency: Awaitable): DotnetToolResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): DotnetToolResourcePromise; + withEndpoints(endpoints: string[]): DotnetToolResourcePromise; + withEnvironmentVariables(variables: Record): DotnetToolResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): DotnetToolResourcePromise; + withMergeLabel(label: string): DotnetToolResourcePromise; + withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; + withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise +export interface DotnetToolResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; + withConfig(config: TestConfigDto): DotnetToolResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; + withCreatedAt(createdAt: string): DotnetToolResourcePromise; + withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; + withCorrelationId(correlationId: string): DotnetToolResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; + withStatus(status: TestResourceStatus): DotnetToolResourcePromise; + withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; + testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; + withDependency(dependency: Awaitable): DotnetToolResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): DotnetToolResourcePromise; + withEndpoints(endpoints: string[]): DotnetToolResourcePromise; + withEnvironmentVariables(variables: Record): DotnetToolResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): DotnetToolResourcePromise; + withMergeLabel(label: string): DotnetToolResourcePromise; + withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; + withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource +export interface ExecutableResource { + withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; + withConfig(config: TestConfigDto): ExecutableResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; + withCreatedAt(createdAt: string): ExecutableResourcePromise; + withModifiedAt(modifiedAt: string): ExecutableResourcePromise; + withCorrelationId(correlationId: string): ExecutableResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; + withStatus(status: TestResourceStatus): ExecutableResourcePromise; + withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; + testWaitFor(dependency: Awaitable): ExecutableResourcePromise; + withDependency(dependency: Awaitable): ExecutableResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExecutableResourcePromise; + withEndpoints(endpoints: string[]): ExecutableResourcePromise; + withEnvironmentVariables(variables: Record): ExecutableResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExecutableResourcePromise; + withMergeLabel(label: string): ExecutableResourcePromise; + withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise +export interface ExecutableResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; + withConfig(config: TestConfigDto): ExecutableResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; + withCreatedAt(createdAt: string): ExecutableResourcePromise; + withModifiedAt(modifiedAt: string): ExecutableResourcePromise; + withCorrelationId(correlationId: string): ExecutableResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; + withStatus(status: TestResourceStatus): ExecutableResourcePromise; + withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; + testWaitFor(dependency: Awaitable): ExecutableResourcePromise; + withDependency(dependency: Awaitable): ExecutableResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExecutableResourcePromise; + withEndpoints(endpoints: string[]): ExecutableResourcePromise; + withEnvironmentVariables(variables: Record): ExecutableResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExecutableResourcePromise; + withMergeLabel(label: string): ExecutableResourcePromise; + withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource +export interface ExternalServiceResource { + withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; + withConfig(config: TestConfigDto): ExternalServiceResourcePromise; + withCreatedAt(createdAt: string): ExternalServiceResourcePromise; + withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; + withCorrelationId(correlationId: string): ExternalServiceResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; + withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; + withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; + testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; + withDependency(dependency: Awaitable): ExternalServiceResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExternalServiceResourcePromise; + withEndpoints(endpoints: string[]): ExternalServiceResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExternalServiceResourcePromise; + withMergeLabel(label: string): ExternalServiceResourcePromise; + withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise +export interface ExternalServiceResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; + withConfig(config: TestConfigDto): ExternalServiceResourcePromise; + withCreatedAt(createdAt: string): ExternalServiceResourcePromise; + withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; + withCorrelationId(correlationId: string): ExternalServiceResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; + withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; + withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; + testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; + withDependency(dependency: Awaitable): ExternalServiceResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExternalServiceResourcePromise; + withEndpoints(endpoints: string[]): ExternalServiceResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExternalServiceResourcePromise; + withMergeLabel(label: string): ExternalServiceResourcePromise; + withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource +export interface ParameterResource { + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; + withConfig(config: TestConfigDto): ParameterResourcePromise; + withCreatedAt(createdAt: string): ParameterResourcePromise; + withModifiedAt(modifiedAt: string): ParameterResourcePromise; + withCorrelationId(correlationId: string): ParameterResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; + withStatus(status: TestResourceStatus): ParameterResourcePromise; + withNestedConfig(config: TestNestedDto): ParameterResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; + testWaitFor(dependency: Awaitable): ParameterResourcePromise; + withDependency(dependency: Awaitable): ParameterResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ParameterResourcePromise; + withEndpoints(endpoints: string[]): ParameterResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ParameterResourcePromise; + withMergeLabel(label: string): ParameterResourcePromise; + withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise +export interface ParameterResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; + withConfig(config: TestConfigDto): ParameterResourcePromise; + withCreatedAt(createdAt: string): ParameterResourcePromise; + withModifiedAt(modifiedAt: string): ParameterResourcePromise; + withCorrelationId(correlationId: string): ParameterResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; + withStatus(status: TestResourceStatus): ParameterResourcePromise; + withNestedConfig(config: TestNestedDto): ParameterResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; + testWaitFor(dependency: Awaitable): ParameterResourcePromise; + withDependency(dependency: Awaitable): ParameterResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ParameterResourcePromise; + withEndpoints(endpoints: string[]): ParameterResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ParameterResourcePromise; + withMergeLabel(label: string): ParameterResourcePromise; + withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource +export interface ProjectResource { + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; + withConfig(config: TestConfigDto): ProjectResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; + withCreatedAt(createdAt: string): ProjectResourcePromise; + withModifiedAt(modifiedAt: string): ProjectResourcePromise; + withCorrelationId(correlationId: string): ProjectResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; + withStatus(status: TestResourceStatus): ProjectResourcePromise; + withNestedConfig(config: TestNestedDto): ProjectResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; + testWaitFor(dependency: Awaitable): ProjectResourcePromise; + withDependency(dependency: Awaitable): ProjectResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ProjectResourcePromise; + withEndpoints(endpoints: string[]): ProjectResourcePromise; + withEnvironmentVariables(variables: Record): ProjectResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ProjectResourcePromise; + withMergeLabel(label: string): ProjectResourcePromise; + withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise +export interface ProjectResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; + withConfig(config: TestConfigDto): ProjectResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; + withCreatedAt(createdAt: string): ProjectResourcePromise; + withModifiedAt(modifiedAt: string): ProjectResourcePromise; + withCorrelationId(correlationId: string): ProjectResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; + withStatus(status: TestResourceStatus): ProjectResourcePromise; + withNestedConfig(config: TestNestedDto): ProjectResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; + testWaitFor(dependency: Awaitable): ProjectResourcePromise; + withDependency(dependency: Awaitable): ProjectResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ProjectResourcePromise; + withEndpoints(endpoints: string[]): ProjectResourcePromise; + withEnvironmentVariables(variables: Record): ProjectResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ProjectResourcePromise; + withMergeLabel(label: string): ProjectResourcePromise; + withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource +export interface Resource { + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withConfig(config: TestConfigDto): ResourcePromise; + withCreatedAt(createdAt: string): ResourcePromise; + withModifiedAt(modifiedAt: string): ResourcePromise; + withCorrelationId(correlationId: string): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withStatus(status: TestResourceStatus): ResourcePromise; + withNestedConfig(config: TestNestedDto): ResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; + testWaitFor(dependency: Awaitable): ResourcePromise; + withDependency(dependency: Awaitable): ResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ResourcePromise; + withEndpoints(endpoints: string[]): ResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ResourcePromise; + withMergeLabel(label: string): ResourcePromise; + withMergeLabelCategorized(label: string, category: string): ResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise +export interface ResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withConfig(config: TestConfigDto): ResourcePromise; + withCreatedAt(createdAt: string): ResourcePromise; + withModifiedAt(modifiedAt: string): ResourcePromise; + withCorrelationId(correlationId: string): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withStatus(status: TestResourceStatus): ResourcePromise; + withNestedConfig(config: TestNestedDto): ResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; + testWaitFor(dependency: Awaitable): ResourcePromise; + withDependency(dependency: Awaitable): ResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ResourcePromise; + withEndpoints(endpoints: string[]): ResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): ResourcePromise; + withMergeLabel(label: string): ResourcePromise; + withMergeLabelCategorized(label: string, category: string): ResourcePromise; + withMergeEndpoint(endpointName: string, port: number): ResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString +export interface ResourceWithConnectionString { + withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise; + withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionStringPromise +export interface ResourceWithConnectionStringPromise { + withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise; + withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironment +export interface ResourceWithEnvironment { + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ResourceWithEnvironmentPromise; + withEnvironmentVariables(variables: Record): ResourceWithEnvironmentPromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironmentPromise +export interface ResourceWithEnvironmentPromise { + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ResourceWithEnvironmentPromise; + withEnvironmentVariables(variables: Record): ResourceWithEnvironmentPromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestConfigDto +export interface TestConfigDto { + name?: string; + port?: number; + enabled?: boolean; + optionalField?: string | null; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestDeeplyNestedDto +export interface TestDeeplyNestedDto { + nestedData?: Record; + metadataArray?: Record[]; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestNestedDto +export interface TestNestedDto { + id?: string; + config?: TestConfigDto; + tags?: string[]; + counts?: Record; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestPersistenceMode +export enum TestPersistenceMode { + None = "None", + Volume = "Volume", + Bind = "Bind", +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestResourceStatus +export enum TestResourceStatus { + Pending = "Pending", + Running = "Running", + Stopped = "Stopped", + Failed = "Failed", +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCallbackContext +export interface TestCallbackContext { + toJSON(): MarshalledHandle; + name: { get: () => Promise; set: (value: string | null) => Promise }; + value: { get: () => Promise; set: (value: number) => Promise }; + cancellationToken: { get: () => Promise; set: (value: AbortSignal | CancellationToken) => Promise }; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContext +export interface TestCollectionContext { + toJSON(): MarshalledHandle; + items(): Promise>; + metadata(): Promise>; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContextPromise +export interface TestCollectionContextPromise extends PromiseLike { + items(): Promise>; + metadata(): Promise>; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource +export interface TestDatabaseResource extends ResourceBuilderBase { + toJSON(): MarshalledHandle; + withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; + withConfig(config: TestConfigDto): TestDatabaseResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; + withCreatedAt(createdAt: string): TestDatabaseResourcePromise; + withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; + withCorrelationId(correlationId: string): TestDatabaseResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; + withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; + withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; + testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; + withDependency(dependency: Awaitable): TestDatabaseResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestDatabaseResourcePromise; + withEndpoints(endpoints: string[]): TestDatabaseResourcePromise; + withEnvironmentVariables(variables: Record): TestDatabaseResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestDatabaseResourcePromise; + withMergeLabel(label: string): TestDatabaseResourcePromise; + withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; + withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise +export interface TestDatabaseResourcePromise extends PromiseLike { + withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; + withConfig(config: TestConfigDto): TestDatabaseResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; + withCreatedAt(createdAt: string): TestDatabaseResourcePromise; + withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; + withCorrelationId(correlationId: string): TestDatabaseResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; + withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; + withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; + testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; + withDependency(dependency: Awaitable): TestDatabaseResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestDatabaseResourcePromise; + withEndpoints(endpoints: string[]): TestDatabaseResourcePromise; + withEnvironmentVariables(variables: Record): TestDatabaseResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestDatabaseResourcePromise; + withMergeLabel(label: string): TestDatabaseResourcePromise; + withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; + withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext +export interface TestEnvironmentContext { + toJSON(): MarshalledHandle; + name: { get: () => Promise; set: (value: string) => Promise }; + description: { get: () => Promise; set: (value: string | null) => Promise }; + priority: { get: () => Promise; set: (value: number) => Promise }; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestMutableCollectionContext +export interface TestMutableCollectionContext { + toJSON(): MarshalledHandle; + readonly tags: AspireList; + readonly counts: AspireDict; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource +export interface TestRedisResource extends ResourceBuilderBase { + toJSON(): MarshalledHandle; + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; + withConfig(config: TestConfigDto): TestRedisResourcePromise; + getTags(): Promise>; + getMetadata(): Promise>; + withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestRedisResourcePromise; + withCreatedAt(createdAt: string): TestRedisResourcePromise; + withModifiedAt(modifiedAt: string): TestRedisResourcePromise; + withCorrelationId(correlationId: string): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withStatus(status: TestResourceStatus): TestRedisResourcePromise; + withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; + testWaitFor(dependency: Awaitable): TestRedisResourcePromise; + getEndpoints(): Promise; + withConnectionStringDirect(connectionString: string): TestRedisResourcePromise; + withRedisSpecific(option: string): TestRedisResourcePromise; + withDependency(dependency: Awaitable): TestRedisResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; + withEndpoints(endpoints: string[]): TestRedisResourcePromise; + withEnvironmentVariables(variables: Record): TestRedisResourcePromise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withMergeLabel(label: string): TestRedisResourcePromise; + withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; + withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise +export interface TestRedisResourcePromise extends PromiseLike { + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; + withConfig(config: TestConfigDto): TestRedisResourcePromise; + getTags(): Promise>; + getMetadata(): Promise>; + withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestRedisResourcePromise; + withCreatedAt(createdAt: string): TestRedisResourcePromise; + withModifiedAt(modifiedAt: string): TestRedisResourcePromise; + withCorrelationId(correlationId: string): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withStatus(status: TestResourceStatus): TestRedisResourcePromise; + withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; + testWaitFor(dependency: Awaitable): TestRedisResourcePromise; + getEndpoints(): Promise; + withConnectionStringDirect(connectionString: string): TestRedisResourcePromise; + withRedisSpecific(option: string): TestRedisResourcePromise; + withDependency(dependency: Awaitable): TestRedisResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; + withEndpoints(endpoints: string[]): TestRedisResourcePromise; + withEnvironmentVariables(variables: Record): TestRedisResourcePromise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withMergeLabel(label: string): TestRedisResourcePromise; + withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; + withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext +export interface TestResourceContext { + toJSON(): MarshalledHandle; + name: { get: () => Promise; set: (value: string) => Promise }; + value: { get: () => Promise; set: (value: number) => Promise }; + getValueAsync(): Promise; + setValueAsync(value: string): TestResourceContextPromise; + validateAsync(): Promise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContextPromise +export interface TestResourceContextPromise extends PromiseLike { + name: { get: () => Promise; set: (value: string) => Promise }; + value: { get: () => Promise; set: (value: number) => Promise }; + getValueAsync(): Promise; + setValueAsync(value: string): TestResourceContextPromise; + validateAsync(): Promise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource +export interface TestVaultResource extends ResourceBuilderBase { + toJSON(): MarshalledHandle; + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; + withConfig(config: TestConfigDto): TestVaultResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; + withCreatedAt(createdAt: string): TestVaultResourcePromise; + withModifiedAt(modifiedAt: string): TestVaultResourcePromise; + withCorrelationId(correlationId: string): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withStatus(status: TestResourceStatus): TestVaultResourcePromise; + withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; + testWaitFor(dependency: Awaitable): TestVaultResourcePromise; + withDependency(dependency: Awaitable): TestVaultResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestVaultResourcePromise; + withEndpoints(endpoints: string[]): TestVaultResourcePromise; + withEnvironmentVariables(variables: Record): TestVaultResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestVaultResourcePromise; + withVaultDirect(option: string): TestVaultResourcePromise; + withMergeLabel(label: string): TestVaultResourcePromise; + withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; + withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise +export interface TestVaultResourcePromise extends PromiseLike { + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; + withConfig(config: TestConfigDto): TestVaultResourcePromise; + testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; + withCreatedAt(createdAt: string): TestVaultResourcePromise; + withModifiedAt(modifiedAt: string): TestVaultResourcePromise; + withCorrelationId(correlationId: string): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withStatus(status: TestResourceStatus): TestVaultResourcePromise; + withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; + withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; + testWaitFor(dependency: Awaitable): TestVaultResourcePromise; + withDependency(dependency: Awaitable): TestVaultResourcePromise; + withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestVaultResourcePromise; + withEndpoints(endpoints: string[]): TestVaultResourcePromise; + withEnvironmentVariables(variables: Record): TestVaultResourcePromise; + withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestVaultResourcePromise; + withVaultDirect(option: string): TestVaultResourcePromise; + withMergeLabel(label: string): TestVaultResourcePromise; + withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; + withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; + withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; + withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions +export interface AddTestChildDatabaseOptions { + databaseName?: string; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions +export interface AddTestRedisOptions { + port?: number; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions +export interface GetStatusAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions +export interface WaitForReadyAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithDataVolumeOptions +export interface WithDataVolumeOptions { + name?: string; + isReadOnly?: boolean; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions +export interface WithMergeLoggingOptions { + enableConsole?: boolean; + maxFiles?: number; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions +export interface WithMergeLoggingPathOptions { + enableConsole?: boolean; + maxFiles?: number; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions +export interface WithOptionalCallbackOptions { + callback?: (arg: TestCallbackContext) => Promise; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions +export interface WithOptionalStringOptions { + value?: string; + enabled?: boolean; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithPersistenceOptions +export interface WithPersistenceOptions { + mode?: TestPersistenceMode; +} + +// Aspire.Hosting:opaque:CSharpAppResource +export interface CSharpAppResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:CSharpAppResourcePromise +export interface CSharpAppResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ContainerRegistryResource +export interface ContainerRegistryResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ContainerRegistryResourcePromise +export interface ContainerRegistryResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ContainerResource +export interface ContainerResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ContainerResourcePromise +export interface ContainerResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:DistributedApplicationBuilder +export interface DistributedApplicationBuilder extends HandleReference {} + +// Aspire.Hosting:opaque:DistributedApplicationBuilderPromise +export interface DistributedApplicationBuilderPromise extends PromiseLike {} + +// Aspire.Hosting:opaque:DotnetToolResource +export interface DotnetToolResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:DotnetToolResourcePromise +export interface DotnetToolResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ExecutableResource +export interface ExecutableResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ExecutableResourcePromise +export interface ExecutableResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ExternalServiceResource +export interface ExternalServiceResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ExternalServiceResourcePromise +export interface ExternalServiceResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ParameterResource +export interface ParameterResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ParameterResourcePromise +export interface ParameterResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ProjectResource +export interface ProjectResource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ProjectResourcePromise +export interface ProjectResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:Resource +export interface Resource extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ResourcePromise +export interface ResourcePromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ResourceWithConnectionString +export interface ResourceWithConnectionString extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ResourceWithConnectionStringPromise +export interface ResourceWithConnectionStringPromise extends PromiseLike {} + +// Aspire.Hosting:opaque:ResourceWithEnvironment +export interface ResourceWithEnvironment extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ResourceWithEnvironmentPromise +export interface ResourceWithEnvironmentPromise extends PromiseLike {} + +// aspire:runtime:base +export type Awaitable = T | PromiseLike; +export interface MarshalledHandle { $handle: string; } +export interface HandleReference { toJSON(): MarshalledHandle; } +export interface CancellationToken { readonly aborted: boolean; } +export interface ReferenceExpression { readonly value: Promise; } +export interface AspireList extends HandleReference { get(index: number): Promise; } +export interface AspireDict extends HandleReference { get(key: TKey): Promise; } +export interface ResourceBuilderBase extends HandleReference {} +export interface InteractionInput { readonly name: string; } +export interface InteractionInputCollection extends HandleReference {} +export interface InteractionInputCollectionPromise extends PromiseLike {} \ No newline at end of file diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json new file mode 100644 index 00000000000..851dc285b99 --- /dev/null +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -0,0 +1,6934 @@ +{ + "schemaVersion": 1, + "language": "typescript", + "package": { + "name": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "version": "13.5.0" + }, + "modules": [ + { + "name": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "items": [ + { + "id": "dto:TestConfigDto", + "kind": "dto", + "name": "TestConfigDto", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestConfigDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestConfigDto", + "summary": "Test DTO to verify [AspireDto] generates TypeScript interfaces.", + "members": [ + { + "id": "property:TestConfigDto.name", + "kind": "property", + "name": "name", + "declaration": "name?: string", + "summary": "The name of the test config." + }, + { + "id": "property:TestConfigDto.port", + "kind": "property", + "name": "port", + "declaration": "port?: number", + "summary": "The port used by the test config." + }, + { + "id": "property:TestConfigDto.enabled", + "kind": "property", + "name": "enabled", + "declaration": "enabled?: boolean", + "summary": "A value indicating whether the test config is enabled." + }, + { + "id": "property:TestConfigDto.optionalField", + "kind": "property", + "name": "optionalField", + "declaration": "optionalField?: string | null", + "summary": "An optional test config field." + } + ] + }, + { + "id": "dto:TestDeeplyNestedDto", + "kind": "dto", + "name": "TestDeeplyNestedDto", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestDeeplyNestedDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestDeeplyNestedDto", + "summary": "Test DTO with deeply nested generic types.", + "members": [ + { + "id": "property:TestDeeplyNestedDto.nestedData", + "kind": "property", + "name": "nestedData", + "declaration": "nestedData?: Record\u003Cstring, TestConfigDto[]\u003E", + "summary": "Deeply nested generic: Dictionary containing List of DTOs." + }, + { + "id": "property:TestDeeplyNestedDto.metadataArray", + "kind": "property", + "name": "metadataArray", + "declaration": "metadataArray?: Record\u003Cstring, string\u003E[]", + "summary": "Array of dictionaries." + } + ] + }, + { + "id": "dto:TestNestedDto", + "kind": "dto", + "name": "TestNestedDto", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestNestedDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestNestedDto", + "summary": "Test DTO with complex nested types.", + "members": [ + { + "id": "property:TestNestedDto.id", + "kind": "property", + "name": "id", + "declaration": "id?: string" + }, + { + "id": "property:TestNestedDto.config", + "kind": "property", + "name": "config", + "declaration": "config?: TestConfigDto" + }, + { + "id": "property:TestNestedDto.tags", + "kind": "property", + "name": "tags", + "declaration": "tags?: string[]" + }, + { + "id": "property:TestNestedDto.counts", + "kind": "property", + "name": "counts", + "declaration": "counts?: Record\u003Cstring, number\u003E" + } + ] + }, + { + "id": "enum:TestPersistenceMode", + "kind": "enum", + "name": "TestPersistenceMode", + "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestPersistenceMode", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export enum TestPersistenceMode", + "summary": "Test persistence mode enum.", + "members": [ + { + "id": "enumValue:TestPersistenceMode.None", + "kind": "property", + "name": "None", + "declaration": "None = \u0022None\u0022" + }, + { + "id": "enumValue:TestPersistenceMode.Volume", + "kind": "property", + "name": "Volume", + "declaration": "Volume = \u0022Volume\u0022" + }, + { + "id": "enumValue:TestPersistenceMode.Bind", + "kind": "property", + "name": "Bind", + "declaration": "Bind = \u0022Bind\u0022" + } + ] + }, + { + "id": "enum:TestResourceStatus", + "kind": "enum", + "name": "TestResourceStatus", + "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestResourceStatus", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export enum TestResourceStatus", + "summary": "Test enum for type generation verification.", + "members": [ + { + "id": "enumValue:TestResourceStatus.Pending", + "kind": "property", + "name": "Pending", + "declaration": "Pending = \u0022Pending\u0022", + "summary": "The resource is pending." + }, + { + "id": "enumValue:TestResourceStatus.Running", + "kind": "property", + "name": "Running", + "declaration": "Running = \u0022Running\u0022", + "summary": "The resource is running." + }, + { + "id": "enumValue:TestResourceStatus.Stopped", + "kind": "property", + "name": "Stopped", + "declaration": "Stopped = \u0022Stopped\u0022", + "summary": "The resource is stopped." + }, + { + "id": "enumValue:TestResourceStatus.Failed", + "kind": "property", + "name": "Failed", + "declaration": "Failed = \u0022Failed\u0022", + "summary": "The resource failed." + } + ] + }, + { + "id": "interface:CSharpAppResource", + "kind": "interface", + "name": "CSharpAppResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.CSharpAppResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface CSharpAppResource extends ResourceBuilderBase", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:CSharpAppResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "CSharpAppResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:CSharpAppResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "CSharpAppResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "CSharpAppResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "CSharpAppResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:CSharpAppResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "CSharpAppResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "CSharpAppResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "CSharpAppResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "CSharpAppResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "CSharpAppResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "CSharpAppResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "CSharpAppResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "CSharpAppResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "CSharpAppResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "CSharpAppResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:CSharpAppResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "CSharpAppResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ContainerRegistryResource", + "kind": "interface", + "name": "ContainerRegistryResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerRegistryResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ContainerRegistryResource extends ResourceBuilderBase", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ContainerRegistryResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:ContainerRegistryResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:ContainerRegistryResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ContainerRegistryResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "ContainerRegistryResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ContainerResource", + "kind": "interface", + "name": "ContainerResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ContainerResource extends ResourceBuilderBase", + "summary": "A resource that represents a specified container.", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ContainerResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "ContainerResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:ContainerResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "ContainerResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "ContainerResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "ContainerResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "ContainerResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "ContainerResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "ContainerResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:ContainerResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "ContainerResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "ContainerResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "ContainerResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "ContainerResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "ContainerResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "ContainerResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "ContainerResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "ContainerResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "ContainerResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "ContainerResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "ContainerResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "ContainerResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "ContainerResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "ContainerResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ContainerResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "ContainerResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ContainerResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "ContainerResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ContainerResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "ContainerResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:DistributedApplicationBuilder", + "kind": "interface", + "name": "DistributedApplicationBuilder", + "typeId": "Aspire.Hosting/Aspire.Hosting.IDistributedApplicationBuilder", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface DistributedApplicationBuilder", + "summary": "A builder for creating instances of {@ats-ref type:DistributedApplication}.", + "members": [ + { + "id": "method:DistributedApplicationBuilder.addTestRedis", + "kind": "method", + "name": "addTestRedis", + "declaration": "addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestRedis", + "returnType": "TestRedisResourcePromise", + "summary": "Adds a test Redis resource from ATS documentation.", + "parameters": [ + { + "name": "name", + "type": "string", + "optional": false, + "summary": "The ATS resource name." + }, + { + "name": "port", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:DistributedApplicationBuilder.addTestVault", + "kind": "method", + "name": "addTestVault", + "declaration": "addTestVault(name: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestVault", + "returnType": "TestVaultResourcePromise", + "summary": "Adds a test vault resource", + "parameters": [ + { + "name": "name", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:DotnetToolResource", + "kind": "interface", + "name": "DotnetToolResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.DotnetToolResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface DotnetToolResource extends ResourceBuilderBase", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:DotnetToolResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "DotnetToolResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:DotnetToolResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "DotnetToolResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "DotnetToolResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "DotnetToolResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:DotnetToolResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "DotnetToolResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "DotnetToolResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "DotnetToolResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "DotnetToolResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "DotnetToolResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "DotnetToolResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "DotnetToolResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "DotnetToolResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "DotnetToolResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "DotnetToolResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:DotnetToolResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "DotnetToolResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ExecutableResource", + "kind": "interface", + "name": "ExecutableResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ExecutableResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ExecutableResource extends ResourceBuilderBase", + "summary": "A resource that represents a specified executable process.", + "remarks": "You can run any executable command using its full path.\nAs a security feature, Aspire doesn\u0027t run executable unless the command is located in a path listed in the PATH environment variable.\nTo run an executable file that\u0027s in the current directory, specify the full path or use the relative path \u0060./\u0060 to represent the current directory.", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ExecutableResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "ExecutableResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:ExecutableResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "ExecutableResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "ExecutableResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "ExecutableResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "ExecutableResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "ExecutableResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "ExecutableResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:ExecutableResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "ExecutableResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "ExecutableResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "ExecutableResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "ExecutableResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "ExecutableResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "ExecutableResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "ExecutableResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "ExecutableResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "ExecutableResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "ExecutableResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "ExecutableResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "ExecutableResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "ExecutableResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "ExecutableResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ExecutableResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "ExecutableResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ExecutableResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "ExecutableResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ExecutableResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "ExecutableResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ExternalServiceResource", + "kind": "interface", + "name": "ExternalServiceResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ExternalServiceResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ExternalServiceResource extends ResourceBuilderBase", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ExternalServiceResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "ExternalServiceResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:ExternalServiceResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "ExternalServiceResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "ExternalServiceResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "ExternalServiceResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:ExternalServiceResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "ExternalServiceResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "ExternalServiceResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "ExternalServiceResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "ExternalServiceResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "ExternalServiceResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "ExternalServiceResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "ExternalServiceResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "ExternalServiceResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "ExternalServiceResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ExternalServiceResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "ExternalServiceResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ParameterResource", + "kind": "interface", + "name": "ParameterResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ParameterResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ParameterResource extends ResourceBuilderBase", + "summary": "Represents a parameter resource.", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ParameterResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "ParameterResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:ParameterResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "ParameterResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "ParameterResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "ParameterResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "ParameterResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "ParameterResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:ParameterResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "ParameterResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "ParameterResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "ParameterResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "ParameterResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "ParameterResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "ParameterResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "ParameterResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "ParameterResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "ParameterResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "ParameterResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "ParameterResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "ParameterResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "ParameterResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ParameterResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "ParameterResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ParameterResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "ParameterResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ParameterResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "ParameterResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ProjectResource", + "kind": "interface", + "name": "ProjectResource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ProjectResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ProjectResource extends ResourceBuilderBase", + "summary": "A resource that represents a specified .NET project.", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ProjectResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "ProjectResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:ProjectResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "ProjectResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "ProjectResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "ProjectResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "ProjectResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "ProjectResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "ProjectResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:ProjectResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "ProjectResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "ProjectResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "ProjectResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "ProjectResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "ProjectResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "ProjectResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "ProjectResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "ProjectResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "ProjectResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "ProjectResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "ProjectResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "ProjectResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "ProjectResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "ProjectResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ProjectResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "ProjectResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:ProjectResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "ProjectResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:ProjectResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "ProjectResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:Resource", + "kind": "interface", + "name": "Resource", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface Resource extends ResourceBuilderBase", + "summary": "Represents a resource that can be hosted by an application.", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:Resource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "ResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:Resource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "ResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:Resource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "ResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:Resource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "ResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:Resource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "ResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:Resource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "ResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:Resource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "ResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:Resource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "ResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:Resource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "ResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:Resource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "ResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:Resource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "ResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:Resource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "ResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:Resource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "ResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:Resource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "ResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:Resource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "ResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:Resource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "ResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:Resource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "ResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:Resource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "ResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:Resource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "ResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:Resource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "ResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:Resource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "ResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:Resource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "ResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ResourceWithConnectionString", + "kind": "interface", + "name": "ResourceWithConnectionString", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithConnectionString", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ResourceWithConnectionString extends ResourceBuilderBase", + "summary": "Represents a resource that has a connection string associated with it.", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ResourceWithConnectionString.withConnectionString", + "kind": "method", + "name": "withConnectionString", + "declaration": "withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionString", + "returnType": "ResourceWithConnectionStringPromise", + "summary": "Sets the connection string using a reference expression", + "parameters": [ + { + "name": "connectionString", + "type": "ReferenceExpression", + "optional": false + } + ] + }, + { + "id": "method:ResourceWithConnectionString.withConnectionStringDirect", + "kind": "method", + "name": "withConnectionStringDirect", + "declaration": "withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionStringDirect", + "returnType": "ResourceWithConnectionStringPromise", + "summary": "Sets connection string using direct interface target", + "parameters": [ + { + "name": "connectionString", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:ResourceWithEnvironment", + "kind": "interface", + "name": "ResourceWithEnvironment", + "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithEnvironment", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface ResourceWithEnvironment extends ResourceBuilderBase", + "summary": "Represents a resource that is associated with an environment.", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:ResourceWithEnvironment.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ResourceWithEnvironmentPromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "ResourceWithEnvironmentPromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:ResourceWithEnvironment.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ResourceWithEnvironmentPromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "ResourceWithEnvironmentPromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:TestCallbackContext", + "kind": "interface", + "name": "TestCallbackContext", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestCallbackContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestCallbackContext", + "summary": "Test callback context for WithCustomCallback. Also used to verify [AspireExport(ExposeProperties = true)] scanning.", + "members": [ + { + "id": "property:TestCallbackContext.name", + "kind": "property", + "name": "name", + "declaration": "name: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCallbackContext.name" + }, + { + "id": "property:TestCallbackContext.value", + "kind": "property", + "name": "value", + "declaration": "value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCallbackContext.value" + }, + { + "id": "property:TestCallbackContext.cancellationToken", + "kind": "property", + "name": "cancellationToken", + "declaration": "cancellationToken: { get: () =\u003E Promise\u003CCancellationToken\u003E; set: (value: AbortSignal | CancellationToken) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCallbackContext.cancellationToken", + "summary": "CancellationToken is supported by ATS." + } + ] + }, + { + "id": "interface:TestCollectionContext", + "kind": "interface", + "name": "TestCollectionContext", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestCollectionContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestCollectionContext", + "summary": "Test context with collection properties to verify consistent code generation. Verifies both List and Dictionary properties generate proper getter patterns.", + "members": [ + { + "id": "property:TestCollectionContext.items", + "kind": "property", + "name": "items", + "declaration": "items(): Promise\u003CAspireList\u003Cstring\u003E\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCollectionContext.items", + "summary": "List property - should generate AspireList getter like Dictionary properties." + }, + { + "id": "property:TestCollectionContext.metadata", + "kind": "property", + "name": "metadata", + "declaration": "metadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCollectionContext.metadata", + "summary": "Dictionary property - already works with AspireDict getter." + } + ] + }, + { + "id": "interface:TestDatabaseResource", + "kind": "interface", + "name": "TestDatabaseResource", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestDatabaseResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestDatabaseResource extends ResourceBuilderBase", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:TestDatabaseResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "TestDatabaseResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:TestDatabaseResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "TestDatabaseResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "TestDatabaseResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "TestDatabaseResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:TestDatabaseResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "TestDatabaseResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "TestDatabaseResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "TestDatabaseResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "TestDatabaseResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "TestDatabaseResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "TestDatabaseResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "TestDatabaseResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "TestDatabaseResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "TestDatabaseResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "TestDatabaseResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:TestDatabaseResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "TestDatabaseResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:TestEnvironmentContext", + "kind": "interface", + "name": "TestEnvironmentContext", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestEnvironmentContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestEnvironmentContext", + "summary": "Test environment context used in callbacks. Verifies property-like object pattern (ctx.name.get(), ctx.name.set()).", + "members": [ + { + "id": "property:TestEnvironmentContext.name", + "kind": "property", + "name": "name", + "declaration": "name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestEnvironmentContext.name" + }, + { + "id": "property:TestEnvironmentContext.description", + "kind": "property", + "name": "description", + "declaration": "description: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestEnvironmentContext.description" + }, + { + "id": "property:TestEnvironmentContext.priority", + "kind": "property", + "name": "priority", + "declaration": "priority: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestEnvironmentContext.priority" + } + ] + }, + { + "id": "interface:TestMutableCollectionContext", + "kind": "interface", + "name": "TestMutableCollectionContext", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestMutableCollectionContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestMutableCollectionContext", + "members": [ + { + "id": "property:TestMutableCollectionContext.tags", + "kind": "property", + "name": "tags", + "declaration": "readonly tags: AspireList\u003Cstring\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestMutableCollectionContext.tags" + }, + { + "id": "property:TestMutableCollectionContext.counts", + "kind": "property", + "name": "counts", + "declaration": "readonly counts: AspireDict\u003Cstring, number\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestMutableCollectionContext.counts" + } + ] + }, + { + "id": "interface:TestRedisResource", + "kind": "interface", + "name": "TestRedisResource", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestRedisResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestRedisResource extends ResourceBuilderBase", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:TestRedisResource.addTestChildDatabase", + "kind": "method", + "name": "addTestChildDatabase", + "declaration": "addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestChildDatabase", + "returnType": "TestDatabaseResourcePromise", + "summary": "Adds a child database to a test Redis resource", + "remarks": "This method tests the factory method codegen pattern where a method on builder type A\nreturns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource).", + "parameters": [ + { + "name": "name", + "type": "string", + "optional": false + }, + { + "name": "databaseName", + "type": "string", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withPersistence", + "kind": "method", + "name": "withPersistence", + "declaration": "withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withPersistence", + "returnType": "TestRedisResourcePromise", + "summary": "Configures the Redis resource with persistence", + "parameters": [ + { + "name": "mode", + "type": "TestPersistenceMode", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "TestRedisResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "TestRedisResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.getTags", + "kind": "method", + "name": "getTags", + "declaration": "getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getTags", + "returnType": "Promise\u003CAspireList\u003Cstring\u003E\u003E", + "summary": "Gets the tags for the resource" + }, + { + "id": "method:TestRedisResource.getMetadata", + "kind": "method", + "name": "getMetadata", + "declaration": "getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getMetadata", + "returnType": "Promise\u003CAspireDict\u003Cstring, string\u003E\u003E", + "summary": "Gets the metadata for the resource" + }, + { + "id": "method:TestRedisResource.withConnectionString", + "kind": "method", + "name": "withConnectionString", + "declaration": "withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionString", + "returnType": "TestRedisResourcePromise", + "summary": "Sets the connection string using a reference expression", + "parameters": [ + { + "name": "connectionString", + "type": "ReferenceExpression", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "TestRedisResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "TestRedisResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "TestRedisResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "TestRedisResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "TestRedisResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "TestRedisResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "TestRedisResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "TestRedisResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "TestRedisResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.getEndpoints", + "kind": "method", + "name": "getEndpoints", + "declaration": "getEndpoints(): Promise\u003Cstring[]\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getEndpoints", + "returnType": "Promise\u003Cstring[]\u003E", + "summary": "Gets the endpoints" + }, + { + "id": "method:TestRedisResource.withConnectionStringDirect", + "kind": "method", + "name": "withConnectionStringDirect", + "declaration": "withConnectionStringDirect(connectionString: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionStringDirect", + "returnType": "TestRedisResourcePromise", + "summary": "Sets connection string using direct interface target", + "parameters": [ + { + "name": "connectionString", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withRedisSpecific", + "kind": "method", + "name": "withRedisSpecific", + "declaration": "withRedisSpecific(option: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withRedisSpecific", + "returnType": "TestRedisResourcePromise", + "summary": "Redis-specific configuration", + "parameters": [ + { + "name": "option", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "TestRedisResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "TestRedisResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "TestRedisResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "TestRedisResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.getStatusAsync", + "kind": "method", + "name": "getStatusAsync", + "declaration": "getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getStatusAsync", + "returnType": "Promise\u003Cstring\u003E", + "summary": "Gets the status of the resource asynchronously", + "parameters": [ + { + "name": "cancellationToken", + "type": "AbortSignal | CancellationToken", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "TestRedisResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.waitForReadyAsync", + "kind": "method", + "name": "waitForReadyAsync", + "declaration": "waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync", + "returnType": "Promise\u003Cboolean\u003E", + "summary": "Waits for the resource to be ready", + "parameters": [ + { + "name": "timeout", + "type": "number", + "optional": false + }, + { + "name": "cancellationToken", + "type": "AbortSignal | CancellationToken", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withMultiParamHandleCallback", + "kind": "method", + "name": "withMultiParamHandleCallback", + "declaration": "withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMultiParamHandleCallback", + "returnType": "TestRedisResourcePromise", + "summary": "Tests multi-param callback destructuring", + "parameters": [ + { + "name": "callback", + "type": "(arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withDataVolume", + "kind": "method", + "name": "withDataVolume", + "declaration": "withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDataVolume", + "returnType": "TestRedisResourcePromise", + "summary": "Adds a data volume with persistence", + "parameters": [ + { + "name": "name", + "type": "string", + "optional": true + }, + { + "name": "isReadOnly", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "TestRedisResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "TestRedisResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "TestRedisResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "TestRedisResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "TestRedisResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "TestRedisResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:TestRedisResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "TestRedisResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:TestRedisResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "TestRedisResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "interface:TestResourceContext", + "kind": "interface", + "name": "TestResourceContext", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestResourceContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestResourceContext", + "summary": "Test context type with exposed instance methods. Verifies [AspireExport(ExposeMethods=true)] generates async methods.", + "members": [ + { + "id": "property:TestResourceContext.name", + "kind": "property", + "name": "name", + "declaration": "name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.name" + }, + { + "id": "property:TestResourceContext.value", + "kind": "property", + "name": "value", + "declaration": "value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E }", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.value" + }, + { + "id": "method:TestResourceContext.getValueAsync", + "kind": "method", + "name": "getValueAsync", + "declaration": "getValueAsync(): Promise\u003Cstring\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.getValueAsync", + "returnType": "Promise\u003Cstring\u003E", + "summary": "Instance method that should be exposed as async method." + }, + { + "id": "method:TestResourceContext.setValueAsync", + "kind": "method", + "name": "setValueAsync", + "declaration": "setValueAsync(value: string): TestResourceContextPromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.setValueAsync", + "returnType": "TestResourceContextPromise", + "summary": "Instance method with parameter.", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestResourceContext.validateAsync", + "kind": "method", + "name": "validateAsync", + "declaration": "validateAsync(): Promise\u003Cboolean\u003E", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.validateAsync", + "returnType": "Promise\u003Cboolean\u003E", + "summary": "Instance method with return type." + } + ] + }, + { + "id": "interface:TestVaultResource", + "kind": "interface", + "name": "TestVaultResource", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestVaultResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestVaultResource extends ResourceBuilderBase", + "extends": [ + "ResourceBuilderBase" + ], + "members": [ + { + "id": "method:TestVaultResource.withOptionalString", + "kind": "method", + "name": "withOptionalString", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", + "returnType": "TestVaultResourcePromise", + "summary": "Adds an optional string parameter", + "parameters": [ + { + "name": "value", + "type": "string", + "optional": true + }, + { + "name": "enabled", + "type": "boolean", + "optional": true + } + ] + }, + { + "id": "method:TestVaultResource.withConfig", + "kind": "method", + "name": "withConfig", + "declaration": "withConfig(config: TestConfigDto): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", + "returnType": "TestVaultResourcePromise", + "summary": "Configures the resource with a DTO", + "parameters": [ + { + "name": "config", + "type": "TestConfigDto", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.testWithEnvironmentCallback", + "kind": "method", + "name": "testWithEnvironmentCallback", + "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", + "returnType": "TestVaultResourcePromise", + "summary": "Configures environment with callback (test version)", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withCreatedAt", + "kind": "method", + "name": "withCreatedAt", + "declaration": "withCreatedAt(createdAt: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", + "returnType": "TestVaultResourcePromise", + "summary": "Sets the created timestamp", + "parameters": [ + { + "name": "createdAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withModifiedAt", + "kind": "method", + "name": "withModifiedAt", + "declaration": "withModifiedAt(modifiedAt: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", + "returnType": "TestVaultResourcePromise", + "summary": "Sets the modified timestamp", + "parameters": [ + { + "name": "modifiedAt", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withCorrelationId", + "kind": "method", + "name": "withCorrelationId", + "declaration": "withCorrelationId(correlationId: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", + "returnType": "TestVaultResourcePromise", + "summary": "Sets the correlation ID", + "parameters": [ + { + "name": "correlationId", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withOptionalCallback", + "kind": "method", + "name": "withOptionalCallback", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", + "returnType": "TestVaultResourcePromise", + "summary": "Configures with optional callback", + "parameters": [ + { + "name": "callback", + "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "optional": true + } + ] + }, + { + "id": "method:TestVaultResource.withStatus", + "kind": "method", + "name": "withStatus", + "declaration": "withStatus(status: TestResourceStatus): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", + "returnType": "TestVaultResourcePromise", + "summary": "Sets the resource status", + "parameters": [ + { + "name": "status", + "type": "TestResourceStatus", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withNestedConfig", + "kind": "method", + "name": "withNestedConfig", + "declaration": "withNestedConfig(config: TestNestedDto): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", + "returnType": "TestVaultResourcePromise", + "summary": "Configures with nested DTO", + "parameters": [ + { + "name": "config", + "type": "TestNestedDto", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withValidator", + "kind": "method", + "name": "withValidator", + "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", + "returnType": "TestVaultResourcePromise", + "summary": "Adds validation callback", + "parameters": [ + { + "name": "validator", + "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.testWaitFor", + "kind": "method", + "name": "testWaitFor", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", + "returnType": "TestVaultResourcePromise", + "summary": "Waits for another resource (test version)", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withDependency", + "kind": "method", + "name": "withDependency", + "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", + "returnType": "TestVaultResourcePromise", + "summary": "Adds a dependency on another resource", + "parameters": [ + { + "name": "dependency", + "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withUnionDependency", + "kind": "method", + "name": "withUnionDependency", + "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", + "returnType": "TestVaultResourcePromise", + "summary": "Adds a dependency from a string or another resource", + "parameters": [ + { + "name": "dependency", + "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withEndpoints", + "kind": "method", + "name": "withEndpoints", + "declaration": "withEndpoints(endpoints: string[]): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", + "returnType": "TestVaultResourcePromise", + "summary": "Sets the endpoints", + "parameters": [ + { + "name": "endpoints", + "type": "string[]", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withEnvironmentVariables", + "kind": "method", + "name": "withEnvironmentVariables", + "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", + "returnType": "TestVaultResourcePromise", + "summary": "Sets environment variables", + "parameters": [ + { + "name": "variables", + "type": "Record\u003Cstring, string\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withCancellableOperation", + "kind": "method", + "name": "withCancellableOperation", + "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", + "returnType": "TestVaultResourcePromise", + "summary": "Performs a cancellable operation", + "parameters": [ + { + "name": "operation", + "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withVaultDirect", + "kind": "method", + "name": "withVaultDirect", + "declaration": "withVaultDirect(option: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withVaultDirect", + "returnType": "TestVaultResourcePromise", + "summary": "Configures vault using direct interface target", + "parameters": [ + { + "name": "option", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withMergeLabel", + "kind": "method", + "name": "withMergeLabel", + "declaration": "withMergeLabel(label: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", + "returnType": "TestVaultResourcePromise", + "summary": "Adds a label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withMergeLabelCategorized", + "kind": "method", + "name": "withMergeLabelCategorized", + "declaration": "withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", + "returnType": "TestVaultResourcePromise", + "summary": "Adds a categorized label to the resource", + "parameters": [ + { + "name": "label", + "type": "string", + "optional": false + }, + { + "name": "category", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withMergeEndpoint", + "kind": "method", + "name": "withMergeEndpoint", + "declaration": "withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", + "returnType": "TestVaultResourcePromise", + "summary": "Configures a named endpoint", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withMergeEndpointScheme", + "kind": "method", + "name": "withMergeEndpointScheme", + "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", + "returnType": "TestVaultResourcePromise", + "summary": "Configures a named endpoint with scheme", + "parameters": [ + { + "name": "endpointName", + "type": "string", + "optional": false + }, + { + "name": "port", + "type": "number", + "optional": false + }, + { + "name": "scheme", + "type": "string", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withMergeLogging", + "kind": "method", + "name": "withMergeLogging", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", + "returnType": "TestVaultResourcePromise", + "summary": "Configures resource logging", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:TestVaultResource.withMergeLoggingPath", + "kind": "method", + "name": "withMergeLoggingPath", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", + "returnType": "TestVaultResourcePromise", + "summary": "Configures resource logging with file path", + "parameters": [ + { + "name": "logLevel", + "type": "string", + "optional": false + }, + { + "name": "logPath", + "type": "string", + "optional": false + }, + { + "name": "enableConsole", + "type": "boolean", + "optional": true + }, + { + "name": "maxFiles", + "type": "number", + "optional": true + } + ] + }, + { + "id": "method:TestVaultResource.withMergeRoute", + "kind": "method", + "name": "withMergeRoute", + "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", + "returnType": "TestVaultResourcePromise", + "summary": "Configures a route", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + } + ] + }, + { + "id": "method:TestVaultResource.withMergeRouteMiddleware", + "kind": "method", + "name": "withMergeRouteMiddleware", + "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise", + "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", + "returnType": "TestVaultResourcePromise", + "summary": "Configures a route with middleware", + "parameters": [ + { + "name": "path", + "type": "string", + "optional": false + }, + { + "name": "method", + "type": "string", + "optional": false + }, + { + "name": "handler", + "type": "string", + "optional": false + }, + { + "name": "priority", + "type": "number", + "optional": false + }, + { + "name": "middleware", + "type": "string", + "optional": false + } + ] + } + ] + }, + { + "id": "options:AddTestChildDatabaseOptions", + "kind": "options", + "name": "AddTestChildDatabaseOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestChildDatabaseOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface AddTestChildDatabaseOptions", + "members": [ + { + "id": "property:AddTestChildDatabaseOptions.databaseName", + "kind": "property", + "name": "databaseName", + "declaration": "databaseName?: string" + } + ] + }, + { + "id": "options:AddTestRedisOptions", + "kind": "options", + "name": "AddTestRedisOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestRedisOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface AddTestRedisOptions", + "members": [ + { + "id": "property:AddTestRedisOptions.port", + "kind": "property", + "name": "port", + "declaration": "port?: number" + } + ] + }, + { + "id": "options:GetStatusAsyncOptions", + "kind": "options", + "name": "GetStatusAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/GetStatusAsyncOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface GetStatusAsyncOptions", + "members": [ + { + "id": "property:GetStatusAsyncOptions.cancellationToken", + "kind": "property", + "name": "cancellationToken", + "declaration": "cancellationToken?: AbortSignal | CancellationToken" + } + ] + }, + { + "id": "options:WaitForReadyAsyncOptions", + "kind": "options", + "name": "WaitForReadyAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WaitForReadyAsyncOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WaitForReadyAsyncOptions", + "members": [ + { + "id": "property:WaitForReadyAsyncOptions.cancellationToken", + "kind": "property", + "name": "cancellationToken", + "declaration": "cancellationToken?: AbortSignal | CancellationToken" + } + ] + }, + { + "id": "options:WithDataVolumeOptions", + "kind": "options", + "name": "WithDataVolumeOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithDataVolumeOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WithDataVolumeOptions", + "members": [ + { + "id": "property:WithDataVolumeOptions.name", + "kind": "property", + "name": "name", + "declaration": "name?: string" + }, + { + "id": "property:WithDataVolumeOptions.isReadOnly", + "kind": "property", + "name": "isReadOnly", + "declaration": "isReadOnly?: boolean" + } + ] + }, + { + "id": "options:WithMergeLoggingOptions", + "kind": "options", + "name": "WithMergeLoggingOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WithMergeLoggingOptions", + "members": [ + { + "id": "property:WithMergeLoggingOptions.enableConsole", + "kind": "property", + "name": "enableConsole", + "declaration": "enableConsole?: boolean" + }, + { + "id": "property:WithMergeLoggingOptions.maxFiles", + "kind": "property", + "name": "maxFiles", + "declaration": "maxFiles?: number" + } + ] + }, + { + "id": "options:WithMergeLoggingPathOptions", + "kind": "options", + "name": "WithMergeLoggingPathOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingPathOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WithMergeLoggingPathOptions", + "members": [ + { + "id": "property:WithMergeLoggingPathOptions.enableConsole", + "kind": "property", + "name": "enableConsole", + "declaration": "enableConsole?: boolean" + }, + { + "id": "property:WithMergeLoggingPathOptions.maxFiles", + "kind": "property", + "name": "maxFiles", + "declaration": "maxFiles?: number" + } + ] + }, + { + "id": "options:WithOptionalCallbackOptions", + "kind": "options", + "name": "WithOptionalCallbackOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalCallbackOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WithOptionalCallbackOptions", + "members": [ + { + "id": "property:WithOptionalCallbackOptions.callback", + "kind": "property", + "name": "callback", + "declaration": "callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E" + } + ] + }, + { + "id": "options:WithOptionalStringOptions", + "kind": "options", + "name": "WithOptionalStringOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalStringOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WithOptionalStringOptions", + "members": [ + { + "id": "property:WithOptionalStringOptions.value", + "kind": "property", + "name": "value", + "declaration": "value?: string" + }, + { + "id": "property:WithOptionalStringOptions.enabled", + "kind": "property", + "name": "enabled", + "declaration": "enabled?: boolean" + } + ] + }, + { + "id": "options:WithPersistenceOptions", + "kind": "options", + "name": "WithPersistenceOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithPersistenceOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WithPersistenceOptions", + "members": [ + { + "id": "property:WithPersistenceOptions.mode", + "kind": "property", + "name": "mode", + "declaration": "mode?: TestPersistenceMode" + } + ] + } + ] + } + ], + "declarations": [ + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface CSharpAppResource {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ContainerResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface DotnetToolResource {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ExecutableResource {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ExternalServiceResource {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ParameterResource {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ProjectResource {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface Resource {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ResourceWithConnectionString {\n withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise;\n withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionStringPromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ResourceWithConnectionStringPromise {\n withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise;\n withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironment", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ResourceWithEnvironment {\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ResourceWithEnvironmentPromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ResourceWithEnvironmentPromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironmentPromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface ResourceWithEnvironmentPromise {\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ResourceWithEnvironmentPromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ResourceWithEnvironmentPromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestConfigDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestConfigDto {\n name?: string;\n port?: number;\n enabled?: boolean;\n optionalField?: string | null;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestDeeplyNestedDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestDeeplyNestedDto {\n nestedData?: Record\u003Cstring, TestConfigDto[]\u003E;\n metadataArray?: Record\u003Cstring, string\u003E[];\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestNestedDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestNestedDto {\n id?: string;\n config?: TestConfigDto;\n tags?: string[];\n counts?: Record\u003Cstring, number\u003E;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestPersistenceMode", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export enum TestPersistenceMode {\n None = \u0022None\u0022,\n Volume = \u0022Volume\u0022,\n Bind = \u0022Bind\u0022,\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestResourceStatus", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export enum TestResourceStatus {\n Pending = \u0022Pending\u0022,\n Running = \u0022Running\u0022,\n Stopped = \u0022Stopped\u0022,\n Failed = \u0022Failed\u0022,\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCallbackContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestCallbackContext {\n toJSON(): MarshalledHandle;\n name: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E };\n value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n cancellationToken: { get: () =\u003E Promise\u003CCancellationToken\u003E; set: (value: AbortSignal | CancellationToken) =\u003E Promise\u003Cvoid\u003E };\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestCollectionContext {\n toJSON(): MarshalledHandle;\n items(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n metadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContextPromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestCollectionContextPromise extends PromiseLike\u003CTestCollectionContext\u003E {\n items(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n metadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestEnvironmentContext {\n toJSON(): MarshalledHandle;\n name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E };\n description: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E };\n priority: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestMutableCollectionContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestMutableCollectionContext {\n toJSON(): MarshalledHandle;\n readonly tags: AspireList\u003Cstring\u003E;\n readonly counts: AspireDict\u003Cstring, number\u003E;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestResourceContext {\n toJSON(): MarshalledHandle;\n name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E };\n value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n getValueAsync(): Promise\u003Cstring\u003E;\n setValueAsync(value: string): TestResourceContextPromise;\n validateAsync(): Promise\u003Cboolean\u003E;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContextPromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestResourceContextPromise extends PromiseLike\u003CTestResourceContext\u003E {\n name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E };\n value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n getValueAsync(): Promise\u003Cstring\u003E;\n setValueAsync(value: string): TestResourceContextPromise;\n validateAsync(): Promise\u003Cboolean\u003E;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface AddTestChildDatabaseOptions {\n databaseName?: string;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface AddTestRedisOptions {\n port?: number;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface GetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface WaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithDataVolumeOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface WithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface WithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface WithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface WithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface WithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" + }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithPersistenceOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export interface WithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" + }, + { + "id": "Aspire.Hosting:opaque:CSharpAppResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface CSharpAppResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:CSharpAppResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface CSharpAppResourcePromise extends PromiseLike\u003CCSharpAppResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ContainerRegistryResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ContainerRegistryResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ContainerRegistryResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ContainerRegistryResourcePromise extends PromiseLike\u003CContainerRegistryResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ContainerResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ContainerResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ContainerResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ContainerResourcePromise extends PromiseLike\u003CContainerResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:DistributedApplicationBuilder", + "owningAssembly": "Aspire.Hosting", + "content": "export interface DistributedApplicationBuilder extends HandleReference {}" + }, + { + "id": "Aspire.Hosting:opaque:DistributedApplicationBuilderPromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface DistributedApplicationBuilderPromise extends PromiseLike\u003CDistributedApplicationBuilder\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:DotnetToolResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface DotnetToolResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:DotnetToolResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface DotnetToolResourcePromise extends PromiseLike\u003CDotnetToolResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ExecutableResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ExecutableResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ExecutableResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ExecutableResourcePromise extends PromiseLike\u003CExecutableResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ExternalServiceResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ExternalServiceResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ExternalServiceResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ExternalServiceResourcePromise extends PromiseLike\u003CExternalServiceResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ParameterResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ParameterResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ParameterResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ParameterResourcePromise extends PromiseLike\u003CParameterResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ProjectResource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ProjectResource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ProjectResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ProjectResourcePromise extends PromiseLike\u003CProjectResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:Resource", + "owningAssembly": "Aspire.Hosting", + "content": "export interface Resource extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourcePromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourcePromise extends PromiseLike\u003CResource\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourceWithConnectionString", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithConnectionString extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourceWithConnectionStringPromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithConnectionStringPromise extends PromiseLike\u003CResourceWithConnectionString\u003E {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourceWithEnvironment", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithEnvironment extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourceWithEnvironmentPromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithEnvironmentPromise extends PromiseLike\u003CResourceWithEnvironment\u003E {}" + }, + { + "id": "aspire:runtime:base", + "owningAssembly": "Aspire.Hosting", + "content": "export type Awaitable\u003CT\u003E = T | PromiseLike\u003CT\u003E;\nexport interface MarshalledHandle { $handle: string; }\nexport interface HandleReference { toJSON(): MarshalledHandle; }\nexport interface CancellationToken { readonly aborted: boolean; }\nexport interface ReferenceExpression { readonly value: Promise\u003Cstring\u003E; }\nexport interface AspireList\u003CT\u003E extends HandleReference { get(index: number): Promise\u003CT\u003E; }\nexport interface AspireDict\u003CTKey, TValue\u003E extends HandleReference { get(key: TKey): Promise\u003CTValue\u003E; }\nexport interface ResourceBuilderBase extends HandleReference {}\nexport interface InteractionInput { readonly name: string; }\nexport interface InteractionInputCollection extends HandleReference {}\nexport interface InteractionInputCollectionPromise extends PromiseLike\u003CInteractionInputCollection\u003E {}" + } + ] +} \ No newline at end of file From ab7100e1c6481de794a06f6f1d9bbc1ba0a2c603 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 17:10:30 -0400 Subject: [PATCH 02/73] Expose canonical SDK API exports Adds IApiReferenceExporter as an optional companion to ICodeGenerator, so a language provider can describe the surface it generates without every provider being forced to. AtsTypeScriptCodeGenerator implements it by building the same TypeScriptApiProjector code generation uses, which is what keeps documentation from drifting from emitted source. RemoteHost exposes it as an authenticated exportApi RPC that resolves the existing code generator and then requires the optional interface, rather than introducing a second discovery mechanism. The provider's JSON document is returned verbatim; the payload schema belongs to the language provider. Also fixes a reference-closure bug this uncovered. Types owned by the selected assembly were seeded into AtsContextFilter's included sets directly, so the "was this newly added?" guard refused to walk their own members. An owned DTO exposing an enum from a non-Aspire dependency kept the DTO and dropped the enum, and code generation then failed on the dangling reference -- generateCode for Aspire.Hosting hit this too. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../AtsTypeScriptCodeGenerator.cs | 23 ++- .../AtsContextFilter.cs | 79 +++++++-- .../CodeGeneration/CodeGenerationService.cs | 75 ++++++++ .../CodeGeneration/CodeGeneratorResolver.cs | 17 ++ .../RemoteHostProfilingTelemetry.cs | 8 + .../ApiReferenceExportOptions.cs | 57 ++++++ .../IApiReferenceExporter.cs | 41 +++++ .../api/Aspire.TypeSystem.cs | 18 ++ .../AtsContextFilterTests.cs | 86 ++++++++++ .../CodeGeneration/ApiReferenceExportTests.cs | 162 ++++++++++++++++++ 10 files changed, 552 insertions(+), 14 deletions(-) create mode 100644 src/Aspire.TypeSystem/ApiReferenceExportOptions.cs create mode 100644 src/Aspire.TypeSystem/IApiReferenceExporter.cs create mode 100644 tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index ec072681832..b661fc5508b 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Text; +using System.Text.Json; using System.Text.Json.Nodes; using Aspire.Shared.Json; using Aspire.TypeSystem; @@ -105,7 +106,7 @@ internal sealed class ExportedValueTreeNode /// /// /// -internal sealed class AtsTypeScriptCodeGenerator : ICodeGenerator +internal sealed class AtsTypeScriptCodeGenerator : ICodeGenerator, IApiReferenceExporter { private TextWriter _writer = null!; @@ -443,6 +444,26 @@ public Dictionary GenerateDistributedApplication(AtsContext cont return files; } + /// + public JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options) + { + ArgumentNullException.ThrowIfNull(context); + ArgumentNullException.ThrowIfNull(options); + + // Build the projector from the same context the generator would use, so the exported + // documentation describes the exact signatures generation would emit rather than a + // second, independently derived reading of the ATS context. + var projector = new TypeScriptApiProjector(context); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(options.PackageName, options.PackageVersion), + options.ExportingAssemblyNames); + + // JsonDocument.Parse + Clone rather than JsonSerializer, because this assembly is + // AOT-compatible and the serializer's reflection-based overloads are not. + using var document = JsonDocument.Parse(TypeScriptApiExportWriter.WriteToJson(model)); + return document.RootElement.Clone(); + } + /// /// Generates the aspire.mts SDK file with capability-based API. /// diff --git a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs index 7c5f4d538c0..394c9a33c53 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs @@ -80,6 +80,23 @@ private static AtsContext FilterByExportingAssemblies( if (includeReferencedTypes) { + // Types owned by the selected assemblies were seeded into the included sets directly, + // which means CollectReferencedType's "was this newly added?" guard will refuse to walk + // their own members if a capability later references them. Expand the seeds explicitly so + // an owned DTO's property types survive the filter. Without this, a DTO owned by + // Aspire.Hosting that exposes an enum declared in a non-Aspire dependency (for example + // HealthStatus from Microsoft.Extensions.Diagnostics.HealthChecks) is retained while the + // enum it references is dropped, and code generation then fails on the dangling type. + foreach (var handleType in context.HandleTypes.Where(type => includedHandleTypeIds.Contains(type.AtsTypeId)).ToList()) + { + CollectHandleTypeMembers(handleType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); + } + + foreach (var dtoType in context.DtoTypes.Where(type => includedDtoTypeIds.Contains(type.TypeId)).ToList()) + { + CollectDtoTypeMembers(dtoType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); + } + foreach (var capability in filteredCapabilities) { CollectReferencedType(capability.TargetType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); @@ -156,23 +173,12 @@ private static void CollectReferencedType( if (handleTypesById.TryGetValue(typeRef.TypeId, out var handleType) && includedHandleTypeIds.Add(handleType.AtsTypeId)) { - foreach (var implementedInterface in handleType.ImplementedInterfaces) - { - CollectReferencedType(implementedInterface, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); - } - - foreach (var baseType in handleType.BaseTypeHierarchy) - { - CollectReferencedType(baseType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); - } + CollectHandleTypeMembers(handleType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); } if (dtoTypesById.TryGetValue(typeRef.TypeId, out var dtoType) && includedDtoTypeIds.Add(dtoType.TypeId)) { - foreach (var property in dtoType.Properties) - { - CollectReferencedType(property.Type, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); - } + CollectDtoTypeMembers(dtoType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); } if (enumTypesById.ContainsKey(typeRef.TypeId)) @@ -193,6 +199,53 @@ private static void CollectReferencedType( } } + private static void CollectHandleTypeMembers( + AtsTypeInfo handleType, + IReadOnlyDictionary handleTypesById, + IReadOnlyDictionary dtoTypesById, + IReadOnlyDictionary enumTypesById, + HashSet includedHandleTypeIds, + HashSet includedDtoTypeIds, + HashSet includedEnumTypeIds) + { + foreach (var implementedInterface in handleType.ImplementedInterfaces) + { + CollectReferencedType(implementedInterface, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); + } + + foreach (var baseType in handleType.BaseTypeHierarchy) + { + CollectReferencedType(baseType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); + } + } + + private static void CollectDtoTypeMembers( + AtsDtoTypeInfo dtoType, + IReadOnlyDictionary handleTypesById, + IReadOnlyDictionary dtoTypesById, + IReadOnlyDictionary enumTypesById, + HashSet includedHandleTypeIds, + HashSet includedDtoTypeIds, + HashSet includedEnumTypeIds) + { + foreach (var property in dtoType.Properties) + { + CollectReferencedType(property.Type, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); + + // Callback properties are emitted as function signatures, so their parameter and return + // types are just as load-bearing as the declared property type. + if (property.CallbackParameters is not null) + { + foreach (var callbackParameter in property.CallbackParameters) + { + CollectReferencedType(callbackParameter.Type, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); + } + } + + CollectReferencedType(property.CallbackReturnType, handleTypesById, dtoTypesById, enumTypesById, includedHandleTypeIds, includedDtoTypeIds, includedEnumTypeIds); + } + } + private static bool IsCapabilityOwnedBySelectedAssembly( AtsContext context, AtsCapabilityInfo capability, diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index fd9ff421ad3..e40322936aa 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json; using Aspire.TypeSystem; using Aspire.Hosting.RemoteHost.Diagnostics; using Microsoft.Extensions.Logging; @@ -15,6 +16,7 @@ internal sealed class CodeGenerationService { private const string GetCapabilitiesMethodName = "getCapabilities"; private const string GenerateCodeMethodName = "generateCode"; + private const string ExportApiMethodName = "exportApi"; private readonly JsonRpcAuthenticationState _authenticationState; private readonly AtsContextFactory _atsContextFactory; @@ -268,6 +270,79 @@ public Dictionary GenerateCode(string language, string? assembly } } + /// + /// Exports the canonical API reference for the specified language and package. + /// + /// The target language (e.g., "TypeScript"). + /// The package to export documentation for. + /// The exact resolved version of . + /// The language provider's API reference document, verbatim. + [JsonRpcMethod(ExportApiMethodName)] + public JsonElement ExportApi(string language, string packageName, string packageVersion) + { + using var rpcActivity = _profilingTelemetry.StartJsonRpcServerCall(ExportApiMethodName); + using var activity = _profilingTelemetry.StartCodeGenerationExportApi(language); + try + { + _authenticationState.ThrowIfNotAuthenticated(); + ArgumentException.ThrowIfNullOrWhiteSpace(packageName); + ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); + + _logger.LogDebug(">> exportApi({Language}, {PackageName}, {PackageVersion})", language, packageName, packageVersion); + var sw = System.Diagnostics.Stopwatch.StartNew(); + + var generator = _resolver.GetCodeGenerator(language); + if (generator is null) + { + throw new ArgumentException(BuildNoCodeGeneratorMessage(language)); + } + + if (generator is not IApiReferenceExporter exporter) + { + throw new NotSupportedException( + $"The '{generator.Language}' code generator does not implement {nameof(IApiReferenceExporter)}, " + + "so it cannot produce an API reference export. " + + $"Supported languages for API export: {BuildApiExportLanguageList()}."); + } + + // The reference closure is required for the exported declarations to be self-contained, + // but the exporter still needs the unexpanded set to know which symbols this package + // actually owns and should document. + var context = AtsContextFilter.FilterByExportingAssembliesWithReferences( + _atsContextFactory.GetContext(), + [packageName]); + + var export = exporter.ExportApi(context, new ApiReferenceExportOptions(packageName, packageVersion, [packageName])); + + _logger.LogDebug("<< exportApi({Language}, {PackageName}) completed in {ElapsedMs}ms", language, packageName, sw.ElapsedMilliseconds); + + // Returned verbatim: the payload schema belongs to the language provider, and reshaping + // it here would silently fork the contract documentation consumers bind to. + return export; + } + catch (Exception ex) + { + activity.SetError(ex); + _logger.LogError(ex, "<< exportApi({Language}, {PackageName}) failed", language, packageName); + var wrapped = CodeGenerationDiagnosticBuilder.TryCreateRpcException(ex, _assemblyLoader, _logger); + if (wrapped is not null) + { + throw wrapped; + } + throw; + } + } + + private string BuildApiExportLanguageList() + { + var exportable = _resolver.GetSupportedLanguages() + .Where(language => _resolver.GetApiReferenceExporter(language) is not null) + .OrderBy(language => language, StringComparer.OrdinalIgnoreCase) + .ToArray(); + + return exportable.Length == 0 ? "(none)" : string.Join(", ", exportable); + } + private string BuildNoCodeGeneratorMessage(string language) { var available = _resolver.GetSupportedLanguages() diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs index ea4fcc818c5..d5baa4a9a27 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs @@ -47,6 +47,23 @@ internal CodeGeneratorResolver( return generator; } + /// + /// Gets the API reference exporter for the specified language, if the language's code generator + /// also supports API export. + /// + /// The target language (e.g., "TypeScript", "Python"). + /// + /// The exporter, or when no generator is registered for the language or + /// the registered generator does not implement . + /// + /// + /// This resolves through rather than discovering exporters + /// separately, so an exporter can never be reachable for a language whose code generator is not. + /// A documented API that no generator produces would be worse than no documentation at all. + /// + public IApiReferenceExporter? GetApiReferenceExporter(string language) + => GetCodeGenerator(language) as IApiReferenceExporter; + /// /// Gets the languages of all discovered code generators. /// diff --git a/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs b/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs index 6722dbafade..d07a310ff36 100644 --- a/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs +++ b/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs @@ -46,6 +46,7 @@ internal static class Activities public const string CapabilityInvoke = "aspire.hosting.remotehost.capability.invoke"; public const string CodeGenerationGetCapabilities = "aspire.hosting.remotehost.codegen.get_capabilities"; public const string CodeGenerationGenerate = "aspire.hosting.remotehost.codegen.generate"; + public const string CodeGenerationExportApi = "aspire.hosting.remotehost.codegen.export_api"; public const string LanguageDetect = "aspire.hosting.remotehost.language.detect"; public const string LanguageGetRuntimeSpec = "aspire.hosting.remotehost.language.get_runtime_spec"; public const string LanguageScaffold = "aspire.hosting.remotehost.language.scaffold"; @@ -194,6 +195,13 @@ public ActivityScope StartCodeGenerationGenerate(string language) return activity; } + public ActivityScope StartCodeGenerationExportApi(string language) + { + var activity = StartActivity(Activities.CodeGenerationExportApi, ActivityKind.Server); + activity.SetLanguage(language); + return activity; + } + public ActivityScope StartLanguageDetect() { return StartActivity(Activities.LanguageDetect, ActivityKind.Server); diff --git a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs new file mode 100644 index 00000000000..3cca83b5cdf --- /dev/null +++ b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.TypeSystem; + +/// +/// Describes the package identity and ownership scope of an export. +/// +/// +/// The ATS context handed to an exporter is already filtered to the exporting assemblies plus their +/// reference closure, because the generated code does not type-check without the referenced +/// declarations. That closure is exactly why exists: it lets the +/// exporter tell apart symbols the package owns and should document from symbols it merely needs to +/// emit so the output is self-contained. Without it, every package would republish its dependencies' +/// API reference. +/// +public sealed class ApiReferenceExportOptions +{ + /// + /// Initializes a new instance of the class. + /// + /// The name of the package being exported. + /// The exact version of the package being exported. + /// + /// The assemblies whose symbols this package owns and documents. Symbols outside this set are + /// present only to complete the reference closure. + /// + public ApiReferenceExportOptions( + string packageName, + string packageVersion, + IReadOnlyCollection exportingAssemblyNames) + { + ArgumentException.ThrowIfNullOrWhiteSpace(packageName); + ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); + ArgumentNullException.ThrowIfNull(exportingAssemblyNames); + + PackageName = packageName; + PackageVersion = packageVersion; + ExportingAssemblyNames = exportingAssemblyNames; + } + + /// + /// Gets the name of the package being exported. + /// + public string PackageName { get; } + + /// + /// Gets the exact version of the package being exported. Consumers key published documentation on + /// this value, so it must be a resolved version and never a floating range. + /// + public string PackageVersion { get; } + + /// + /// Gets the assemblies whose symbols this package owns and documents. + /// + public IReadOnlyCollection ExportingAssemblyNames { get; } +} diff --git a/src/Aspire.TypeSystem/IApiReferenceExporter.cs b/src/Aspire.TypeSystem/IApiReferenceExporter.cs new file mode 100644 index 00000000000..0dc026fbf7c --- /dev/null +++ b/src/Aspire.TypeSystem/IApiReferenceExporter.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text.Json; + +namespace Aspire.TypeSystem; + +/// +/// Optional companion to for languages that can describe their +/// generated surface as a machine-readable API reference. +/// +/// +/// +/// Code generation and API export answer different questions. produces +/// the source a user compiles against; this interface produces the documentation model that +/// describes that source. Keeping them separate means a language provider can ship runnable code +/// generation long before it can describe it, and documentation tooling can tell the difference +/// instead of publishing a silently empty reference. +/// +/// +/// The payload schema is owned by the language provider. Hosts must pass the returned document +/// through unmodified so language-specific details survive transport. +/// +/// +public interface IApiReferenceExporter +{ + /// + /// Gets the target language name (for example, "TypeScript"). This must match the + /// value of the generator that produces the same surface, + /// so a host can resolve one from the other. + /// + string Language { get; } + + /// + /// Exports the API reference for the surface the generator would produce from the same context. + /// + /// The ATS context containing capabilities, types, and enums. + /// The package identity and ownership scope for the export. + /// A language-defined JSON document describing the generated API. + JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options); +} diff --git a/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs b/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs index 83f42638aab..2c8b3be551d 100644 --- a/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs +++ b/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs @@ -8,6 +8,17 @@ //------------------------------------------------------------------------------ namespace Aspire.TypeSystem { + public sealed partial class ApiReferenceExportOptions + { + public ApiReferenceExportOptions(string packageName, string packageVersion, System.Collections.Generic.IReadOnlyCollection exportingAssemblyNames) { } + + public System.Collections.Generic.IReadOnlyCollection ExportingAssemblyNames { get { throw null; } } + + public string PackageName { get { throw null; } } + + public string PackageVersion { get { throw null; } } + } + public sealed partial class AspireExportData { public string? Description { get { throw null; } init { } } @@ -459,6 +470,13 @@ public static partial class HostingTypeNames public const string ValueProviderInterface = "Aspire.Hosting.ApplicationModel.IValueProvider"; } + public partial interface IApiReferenceExporter + { + string Language { get; } + + System.Text.Json.JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options); + } + public partial interface ICodeGenerator { string Language { get; } diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index 60d76f4b3c9..a82d4da80b5 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -71,6 +71,92 @@ public void FilterByExportingAssemblies_CodeGenerationFilterIncludesReferencedSu Assert.DoesNotContain(filteredContext.HandleTypes, type => type.AtsTypeId == "Aspire.Hosting/Aspire.Hosting.DistributedApplication"); } + [Fact] + public void FilterByExportingAssemblies_CodeGenerationFilterExpandsOwnedDtoPropertyTypes() + { + // An owned DTO is seeded into the included set up front rather than discovered by walking a + // capability signature, so its own property types used to be skipped entirely. That dropped + // types the generated SDK still emits — in the real context, HealthStatus from + // Microsoft.Extensions.Diagnostics.HealthChecks — and code generation then failed on the + // dangling reference. See https://github.com/microsoft/aspire/issues/17608. + var foreignEnum = new AtsEnumTypeInfo + { + TypeId = AtsConstants.EnumTypeId("Some.Foreign.Dependency.ForeignMode"), + Name = "ForeignMode", + ClrType = typeof(DistributedApplicationOperation), + Values = Enum.GetNames() + }; + + var foreignCallbackEnum = new AtsEnumTypeInfo + { + TypeId = AtsConstants.EnumTypeId("Some.Foreign.Dependency.ForeignCallbackMode"), + Name = "ForeignCallbackMode", + ClrType = typeof(DistributedApplicationOperation), + Values = Enum.GetNames() + }; + + // Owned by the test assembly and referenced by no capability, so only the ownership seed + // pulls it in. + var ownedDtoType = new AtsDtoTypeInfo + { + TypeId = "Aspire.Hosting.RemoteHost.Tests/UnreferencedOptions", + Name = "UnreferencedOptions", + ClrType = typeof(TestOptions), + Properties = + [ + new AtsDtoPropertyInfo + { + Name = "Mode", + Type = new AtsTypeRef + { + TypeId = foreignEnum.TypeId, + ClrType = foreignEnum.ClrType, + Category = AtsTypeCategory.Enum + }, + IsOptional = false + }, + new AtsDtoPropertyInfo + { + Name = "OnConfigure", + Type = new AtsTypeRef { TypeId = AtsConstants.Void, Category = AtsTypeCategory.Primitive }, + IsCallback = true, + CallbackParameters = + [ + new AtsCallbackParameterInfo + { + Name = "mode", + Type = new AtsTypeRef + { + TypeId = foreignCallbackEnum.TypeId, + ClrType = foreignCallbackEnum.ClrType, + Category = AtsTypeCategory.Enum + } + } + ], + IsOptional = true + } + ] + }; + + var context = new AtsContext + { + Capabilities = [], + HandleTypes = [], + DtoTypes = [ownedDtoType], + EnumTypes = [foreignEnum, foreignCallbackEnum], + ExportedValues = [], + Diagnostics = [] + }; + + var filteredContext = AtsContextFilter.FilterByExportingAssembliesWithReferences( + context, + [typeof(AtsContextFilterTests).Assembly.GetName().Name!]); + + Assert.Contains(filteredContext.DtoTypes, type => type.TypeId == ownedDtoType.TypeId); + Assert.Contains(filteredContext.EnumTypes, type => type.TypeId == foreignEnum.TypeId); + Assert.Contains(filteredContext.EnumTypes, type => type.TypeId == foreignCallbackEnum.TypeId); + } + [Fact] public void FilterByExportingAssemblies_ScannedAssemblies_OnlyReturnsSpecifiedAssemblyExports() { diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs new file mode 100644 index 00000000000..77410e468c6 --- /dev/null +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Aspire.Hosting.RemoteHost.CodeGeneration; +using Aspire.Hosting.RemoteHost.Diagnostics; +using Aspire.TypeSystem; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Abstractions; +using Xunit; + +namespace Aspire.Hosting.RemoteHost.Tests; + +/// +/// Covers the canonical API export RPC. The export is what documentation sites bind to, so the +/// contract it enforces matters as much as the payload: exports must be scoped to the requested +/// package, must fail loudly for languages that cannot produce one, and must never be reshaped by +/// RemoteHost. +/// +public class ApiReferenceExportTests +{ + [Fact] + public void ExportApi_TypeScript_ReturnsCanonicalSchemaForRequestedPackage() + { + var service = CreateCodeGenerationService(); + + var export = service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0"); + + Assert.Equal(1, export.GetProperty("schemaVersion").GetInt32()); + Assert.Equal("typescript", export.GetProperty("language").GetString()); + Assert.Equal("Aspire.Hosting", export.GetProperty("package").GetProperty("name").GetString()); + Assert.Equal("13.5.0", export.GetProperty("package").GetProperty("version").GetString()); + + var modules = export.GetProperty("modules").EnumerateArray().ToList(); + Assert.NotEmpty(modules); + + var items = modules.SelectMany(module => module.GetProperty("items").EnumerateArray()).ToList(); + Assert.NotEmpty(items); + + // The whole point of the export is that documented declarations are final TypeScript, not + // ATS type identifiers. + Assert.All(items, item => Assert.DoesNotContain( + "Aspire.Hosting/", + item.GetProperty("declaration").GetString()!, + StringComparison.Ordinal)); + + Assert.NotEmpty(export.GetProperty("declarations").EnumerateArray()); + } + + [Fact] + public void ExportApi_ScopesDocumentedItemsToRequestedPackage() + { + var service = CreateCodeGenerationService(); + + var export = service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0"); + + // Referenced types reach the export through the closure so the declarations type-check, but + // they must not be documented here: the package that owns them publishes them. + var declarationOwners = export.GetProperty("declarations").EnumerateArray() + .Select(declaration => declaration.GetProperty("owningAssembly").GetString()) + .ToHashSet(StringComparer.Ordinal); + + var itemOwners = export.GetProperty("modules").EnumerateArray() + .SelectMany(module => module.GetProperty("items").EnumerateArray()) + .Select(item => item.GetProperty("owningAssembly").GetString()) + .ToHashSet(StringComparer.Ordinal); + + Assert.All(itemOwners, owner => Assert.Equal("Aspire.Hosting", owner)); + Assert.Contains("Aspire.Hosting", declarationOwners); + } + + [Fact] + public void ExportApi_UnknownLanguage_ListsAvailableLanguages() + { + var service = CreateCodeGenerationService(); + + var ex = Assert.Throws(() => service.ExportApi("klingon", "Aspire.Hosting", "13.5.0")); + + Assert.Contains("No code generator found for language: klingon", ex.Message); + Assert.Contains("Available languages:", ex.Message); + } + + [Fact] + public void ExportApi_GeneratorWithoutExporter_ReportsUnsupportedLanguage() + { + var service = CreateCodeGenerationService(); + + // Go generates runtime source but does not implement IApiReferenceExporter, so asking it for + // an API export has to fail with a message that names the gap rather than returning an empty + // document that a documentation site would silently publish. + var ex = Assert.Throws(() => service.ExportApi("Go", "Aspire.Hosting", "13.5.0")); + + Assert.Contains("Go", ex.Message, StringComparison.Ordinal); + Assert.Contains(nameof(IApiReferenceExporter), ex.Message, StringComparison.Ordinal); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ExportApi_MissingPackageName_Throws(string? packageName) + { + var service = CreateCodeGenerationService(); + + Assert.ThrowsAny(() => service.ExportApi("TypeScript", packageName!, "13.5.0")); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ExportApi_MissingPackageVersion_Throws(string? packageVersion) + { + var service = CreateCodeGenerationService(); + + Assert.ThrowsAny(() => service.ExportApi("TypeScript", "Aspire.Hosting", packageVersion!)); + } + + [Fact] + public void ExportApi_RequiresAuthentication() + { + var service = CreateCodeGenerationService(authenticated: false); + + Assert.ThrowsAny(() => service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0")); + } + + private static CodeGenerationService CreateCodeGenerationService(bool authenticated = true) + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["AtsAssemblies:0"] = "Aspire.Hosting.CodeGeneration.Go", + ["AtsAssemblies:1"] = "Aspire.Hosting.CodeGeneration.TypeScript", + }) + .Build(); + + var telemetry = new RemoteHostProfilingTelemetry(new ConfigurationBuilder().Build()); + var loader = new AssemblyLoader(configuration, NullLogger.Instance, telemetry); + + // Do not dispose: the resolver lazily instantiates generators through ActivatorUtilities. + var services = new ServiceCollection().BuildServiceProvider(); + var resolver = new CodeGeneratorResolver(services, loader, NullLogger.Instance); + var atsContextFactory = new AtsContextFactory(loader, NullLogger.Instance, telemetry); + + return new CodeGenerationService( + CreateAuthenticationState(authenticated), + atsContextFactory, + resolver, + loader, + NullLogger.Instance, + telemetry); + } + + // The state starts authenticated when no token is configured, so building an unauthenticated + // service means configuring a token the test never presents. + private static JsonRpcAuthenticationState CreateAuthenticationState(bool authenticated) + => new(authenticated + ? new ConfigurationBuilder().Build() + : new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { ["ASPIRE_REMOTE_APPHOST_TOKEN"] = "test-token" }) + .Build()); +} From ec0099e186782118eea2dcce959e28bd2abb1c7c Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 17:25:22 -0400 Subject: [PATCH 03/73] Add SDK API export command Adds a hidden `aspire sdk export` that asks a scanner AppHost for the canonical API reference of one package in one language and writes it to stdout. Because documentation pipelines consume it, stdout carries exactly one JSON document and every status message goes to stderr, so `aspire sdk export ... > api.json` produces a usable file. The package version must be exact. A document published under a range would describe a different SDK after the next restore, so floating versions are rejected before restore rather than resolved. With no --package, the command defaults to Aspire.Hosting at this CLI's own identity version, which is the whole point: the docs describe the SDK this CLI generates against. SdkCommandPreparation holds only what dump and export genuinely share -- argument parsing, scanner AppHost setup, exporting-assembly discovery. Dump keeps its own serialization and is deliberately not routed through the canonical exporter; a test asserts its payload still has the capabilities shape and no schemaVersion. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- src/Aspire.Cli/Commands/Sdk/SdkCommand.cs | 2 + .../Commands/Sdk/SdkCommandPreparation.cs | 223 +++++++++++++ src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs | 264 +++++---------- .../Commands/Sdk/SdkExportCommand.cs | 209 ++++++++++++ src/Aspire.Cli/Program.cs | 1 + src/Aspire.Cli/Projects/AppHostRpcClient.cs | 4 + src/Aspire.Cli/Projects/IAppHostRpcClient.cs | 14 + .../Commands/Sdk/SdkExportCommandTests.cs | 310 ++++++++++++++++++ .../TestServices/FakeAppHostServerSession.cs | 23 +- tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs | 1 + 10 files changed, 861 insertions(+), 190 deletions(-) create mode 100644 src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs create mode 100644 src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs create mode 100644 tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommand.cs index 05d302dabf4..65e89236b4e 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkCommand.cs @@ -12,11 +12,13 @@ internal sealed class SdkCommand : ParentCommand public SdkCommand( SdkGenerateCommand generateCommand, SdkDumpCommand dumpCommand, + SdkExportCommand exportCommand, CommonCommandServices services) : base("sdk", "Commands for generating SDKs for building Aspire integrations in other languages.", services) { Hidden = true; Subcommands.Add(generateCommand); Subcommands.Add(dumpCommand); + Subcommands.Add(exportCommand); } } diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs new file mode 100644 index 00000000000..50f6a759452 --- /dev/null +++ b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs @@ -0,0 +1,223 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Aspire.Cli.Configuration; +using Aspire.Cli.Interaction; +using Aspire.Cli.Projects; +using Microsoft.Extensions.Logging; +using Semver; + +namespace Aspire.Cli.Commands.Sdk; + +/// +/// The setup that sdk dump and sdk export both need before they can ask an AppHost +/// server anything: turning command-line integration arguments into references, standing up a +/// throwaway scanner AppHost, and working out which assemblies the caller actually asked about. +/// +/// +/// Only the preparation is shared. The two commands ask different questions of the server and +/// serialize the answers differently, and deliberately keeping that apart is what stops +/// sdk dump from quietly becoming an alias for the canonical export. +/// +internal static class SdkCommandPreparation +{ + /// + /// Parses one integration argument, which is either a path to a .csproj or a package + /// reference in PackageName@Version form (for example Aspire.Hosting.Redis@13.5.0). + /// + /// The raw command-line argument. + /// + /// When , floating and range versions are rejected. Callers that publish + /// artifacts keyed on the version need this; a document published under 13.5.* would + /// describe a different SDK after the next restore. + /// + /// The parsed reference when parsing succeeds. + /// The exit code to return when parsing fails. + /// The user-facing failure reason when parsing fails. + /// when the argument was parsed. + public static bool TryParseIntegrationArgument( + string argument, + bool requireExactVersion, + out IntegrationReference? reference, + out int errorExitCode, + out string? errorMessage) + { + reference = null; + errorExitCode = CliExitCodes.InvalidCommand; + errorMessage = null; + + if (argument.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase)) + { + var projectFile = new FileInfo(argument); + if (!projectFile.Exists) + { + errorExitCode = CliExitCodes.FailedToFindProject; + errorMessage = $"Integration project not found: {projectFile.FullName}"; + return false; + } + + reference = IntegrationReference.FromProject( + IntegrationAssemblyNameResolver.Resolve(projectFile), + projectFile.FullName); + return true; + } + + if (!argument.Contains('@')) + { + errorMessage = $"Invalid integration argument '{argument}'. Expected a .csproj path or PackageName@Version format."; + return false; + } + + var atIndex = argument.LastIndexOf('@'); + var packageName = argument[..atIndex]; + var packageVersion = argument[(atIndex + 1)..]; + + if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion) || packageName.Contains('@')) + { + errorMessage = $"Invalid package format '{argument}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@9.2.0)."; + return false; + } + + if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out _)) + { + errorMessage = requireExactVersion + ? $"Invalid version '{packageVersion}' in '{argument}'. Expected an exact NuGet version (e.g. 9.2.0); floating and range versions are not supported." + : $"Invalid version '{packageVersion}' in '{argument}'. Expected a valid NuGet version (e.g. 9.2.0)."; + return false; + } + + reference = IntegrationReference.FromPackage(packageName, packageVersion); + return true; + } + + /// + /// Finds the first assembly name that more than one integration resolves to. + /// + /// The parsed integration references. + /// The duplicated assembly name, or when there is none. + public static string? FindDuplicateAssemblyName(IReadOnlyList integrations) + => integrations + .GroupBy(integration => integration.Name, StringComparer.OrdinalIgnoreCase) + .FirstOrDefault(group => group.Count() > 1)?.Key; + + /// + /// Gets the exporting assembly names to scope a server query to, or when + /// the caller asked for everything. + /// + /// The parsed integration references. + public static string[]? GetExportingAssemblyNames(IReadOnlyList integrations) + => integrations.Count > 0 + ? [.. integrations.Select(integration => integration.Name).Distinct(StringComparer.OrdinalIgnoreCase)] + : null; + + /// + /// Builds and starts a throwaway AppHost server that has the requested integrations restored, and + /// returns a connected RPC client. + /// + /// + /// The returned owns the temporary directory and the server + /// session; disposing it tears both down. Build failures are reported through + /// and surface as a null session rather than an exception, + /// because a failed restore is a user-facing outcome and not a bug. + /// + public static async Task PrepareSessionAsync( + IAppHostServerProjectFactory appHostServerProjectFactory, + IAppHostServerSessionFactory serverSessionFactory, + IInteractionService interactionService, + ILogger logger, + string tempDirectoryPrefix, + string sdkVersion, + IReadOnlyList integrations, + string? packageSourceOverride, + CancellationToken cancellationToken) + { + var tempDirectory = Directory.CreateTempSubdirectory(tempDirectoryPrefix); + var tempDir = tempDirectory.FullName; + var disposeTempDirectory = true; + + try + { + var appHostServerProject = await appHostServerProjectFactory.CreateAsync(tempDir, cancellationToken); + + logger.LogDebug("Building AppHost server with {Count} integrations", integrations.Count); + + var prepareResult = await appHostServerProject.PrepareAsync( + sdkVersion, + integrations, + packageSourceOverride: packageSourceOverride, + cancellationToken: cancellationToken); + + if (!prepareResult.Success) + { + interactionService.DisplayError("Failed to build capability scanner."); + if (prepareResult.Output is not null) + { + foreach (var (_, line) in prepareResult.Output.GetLines()) + { + interactionService.DisplayMessage(KnownEmojis.Wrench, line); + } + } + return null; + } + + var serverSession = serverSessionFactory.Create(appHostServerProject, environmentVariables: null, debug: false, gracefulShutdownSignaler: null, shutdownService: null, isolateConsole: false, cancellationToken); + + // Short-lived RPC session: StartAsync() spawns the server. We never observe the + // exit-code task (WaitForExitAsync) because disposal flows the exit code through the + // activity scope and the only failure mode we care about surfaces via the RPC call. + await serverSession.StartAsync(); + + var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); + + disposeTempDirectory = false; + return new PreparedSdkSession(serverSession, rpcClient, tempDir, logger); + } + finally + { + if (disposeTempDirectory) + { + DeleteTempDirectory(tempDir, logger); + } + } + } + + internal static void DeleteTempDirectory(string tempDir, ILogger logger) + { + try + { + if (Directory.Exists(tempDir)) + { + Directory.Delete(tempDir, recursive: true); + } + } + catch (Exception ex) + { + logger.LogDebug(ex, "Failed to clean up temp directory {TempDir}", tempDir); + } + } +} + +/// +/// A started AppHost scanner server and its connected RPC client. Disposing tears down the server +/// session and deletes the temporary project directory. +/// +internal sealed class PreparedSdkSession( + IAppHostServerSession session, + IAppHostRpcClient rpcClient, + string tempDirectory, + ILogger logger) : IAsyncDisposable +{ + public IAppHostRpcClient RpcClient { get; } = rpcClient; + + public async ValueTask DisposeAsync() + { + try + { + await session.DisposeAsync(); + } + finally + { + SdkCommandPreparation.DeleteTempDirectory(tempDirectory, logger); + } + } +} diff --git a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs index 53695daf237..2f0308ee440 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs @@ -12,7 +12,6 @@ using Aspire.Cli.Projects; using Aspire.Shared.Json; using Microsoft.Extensions.Logging; -using Semver; using Spectre.Console; using StreamJsonRpc; @@ -98,49 +97,23 @@ protected override async Task ExecuteAsync(ParseResult parseResul foreach (var arg in integrationArgs) { - if (arg.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase)) + if (!SdkCommandPreparation.TryParseIntegrationArgument( + arg, + requireExactVersion: false, + out var reference, + out var errorExitCode, + out var errorMessage)) { - var projectFile = new FileInfo(arg); - if (!projectFile.Exists) - { - return CommandResult.Failure(CliExitCodes.FailedToFindProject, $"Integration project not found: {projectFile.FullName}"); - } - - integrations.Add(IntegrationReference.FromProject( - IntegrationAssemblyNameResolver.Resolve(projectFile), - projectFile.FullName)); + return CommandResult.Failure(errorExitCode, errorMessage!); } - else if (arg.Contains('@')) - { - var atIndex = arg.LastIndexOf('@'); - var packageName = arg[..atIndex]; - var packageVersion = arg[(atIndex + 1)..]; - - if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion) || packageName.Contains('@')) - { - return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Invalid package format '{arg}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@9.2.0)."); - } - - if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out _)) - { - return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Invalid version '{packageVersion}' in '{arg}'. Expected a valid NuGet version (e.g. 9.2.0)."); - } - _logger.LogDebug("Parsed package reference {PackageName} version {Version}", packageName, packageVersion); - integrations.Add(IntegrationReference.FromPackage(packageName, packageVersion)); - } - else - { - return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Invalid integration argument '{arg}'. Expected a .csproj path or PackageName@Version format."); - } + _logger.LogDebug("Parsed integration reference {IntegrationName}", reference!.Name); + integrations.Add(reference); } - var duplicateIntegration = integrations - .GroupBy(integration => integration.Name, StringComparer.OrdinalIgnoreCase) - .FirstOrDefault(group => group.Count() > 1); - if (duplicateIntegration is not null) + if (SdkCommandPreparation.FindDuplicateAssemblyName(integrations) is { } duplicateAssemblyName) { - return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Multiple integrations resolve to assembly name '{duplicateIntegration.Key}'."); + return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Multiple integrations resolve to assembly name '{duplicateAssemblyName}'."); } if (outputDirectory is not null) @@ -166,97 +139,59 @@ private async Task DumpCapabilitiesAsync( OutputFormat format, CancellationToken cancellationToken) { - var tempDirectory = Directory.CreateTempSubdirectory("aspire-sdk-dump-"); - var tempDir = tempDirectory.FullName; - - try + await using var session = await SdkCommandPreparation.PrepareSessionAsync( + _appHostServerProjectFactory, + _serverSessionFactory, + InteractionService, + _logger, + "aspire-sdk-dump-", + ExecutionContext.IdentityVersion, + integrations, + packageSourceOverride: null, + cancellationToken); + + if (session is null) { - var appHostServerProject = await _appHostServerProjectFactory.CreateAsync(tempDir, cancellationToken); - - _logger.LogDebug("Building AppHost server for capability scanning with {Count} integrations", integrations.Count); - - var prepareResult = await appHostServerProject.PrepareAsync( - ExecutionContext.IdentityVersion, - integrations, - cancellationToken: cancellationToken); - - if (!prepareResult.Success) - { - InteractionService.DisplayError("Failed to build capability scanner."); - if (prepareResult.Output is not null) - { - foreach (var (_, line) in prepareResult.Output.GetLines()) - { - InteractionService.DisplayMessage(KnownEmojis.Wrench, line); - } - } - return CliExitCodes.FailedToBuildArtifacts; - } - - await using var serverSession = _serverSessionFactory.Create(appHostServerProject, environmentVariables: null, debug: false, gracefulShutdownSignaler: null, shutdownService: null, isolateConsole: false, cancellationToken); - // Short-lived RPC session: StartAsync() spawns the server. We never observe the - // exit-code task (WaitForExitAsync) because disposal flows the exit code through the - // activity scope and the only failure mode we care about surfaces via the RPC call below. - await serverSession.StartAsync(); - - // Connect and get capabilities - var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); + return CliExitCodes.FailedToBuildArtifacts; + } - var exportAssemblyNames = integrations.Count > 0 - ? integrations.Select(i => i.Name).Distinct(StringComparer.OrdinalIgnoreCase).ToArray() - : null; + var exportAssemblyNames = SdkCommandPreparation.GetExportingAssemblyNames(integrations); - _logger.LogDebug("Fetching capabilities via RPC"); - var capabilities = exportAssemblyNames is not null - ? await rpcClient.GetCapabilitiesForAssembliesAsync(exportAssemblyNames, cancellationToken) - : await rpcClient.GetCapabilitiesAsync(cancellationToken); + _logger.LogDebug("Fetching capabilities via RPC"); + var capabilities = exportAssemblyNames is not null + ? await session.RpcClient.GetCapabilitiesForAssembliesAsync(exportAssemblyNames, cancellationToken) + : await session.RpcClient.GetCapabilitiesAsync(cancellationToken); - PrepareCapabilitiesForOutput(capabilities, integrations); + PrepareCapabilitiesForOutput(capabilities, integrations); - // Format the output - var output = format switch - { - OutputFormat.Json => FormatJson(capabilities), - OutputFormat.Ci => FormatCi(capabilities), - _ => FormatPretty(capabilities) - }; + // Format the output + var output = format switch + { + OutputFormat.Json => FormatJson(capabilities), + OutputFormat.Ci => FormatCi(capabilities), + _ => FormatPretty(capabilities) + }; - // Write output - if (outputFile is not null) - { - var outputDir = outputFile.Directory; - if (outputDir is not null && !outputDir.Exists) - { - outputDir.Create(); - } - await File.WriteAllTextAsync(outputFile.FullName, output, cancellationToken); - InteractionService.DisplaySuccess($"Capabilities written to {outputFile.FullName}"); - } - else + // Write output + if (outputFile is not null) + { + var outputDir = outputFile.Directory; + if (outputDir is not null && !outputDir.Exists) { - // Output to stdout - InteractionService.DisplayRawText(output, consoleOverride: ConsoleOutput.Standard); + outputDir.Create(); } - - // Return error code if there are errors in diagnostics - var hasErrors = capabilities.Diagnostics.Exists(d => d.Severity == "Error"); - return hasErrors ? CliExitCodes.InvalidCommand : CliExitCodes.Success; + await File.WriteAllTextAsync(outputFile.FullName, output, cancellationToken); + InteractionService.DisplaySuccess($"Capabilities written to {outputFile.FullName}"); } - finally + else { - // Clean up temp directory - try - { - if (Directory.Exists(tempDir)) - { - Directory.Delete(tempDir, recursive: true); - } - } - catch (Exception ex) - { - _logger.LogDebug(ex, "Failed to clean up temp directory {TempDir}", tempDir); - } + // Output to stdout + InteractionService.DisplayRawText(output, consoleOverride: ConsoleOutput.Standard); } + + // Return error code if there are errors in diagnostics + var hasErrors = capabilities.Diagnostics.Exists(d => d.Severity == "Error"); + return hasErrors ? CliExitCodes.InvalidCommand : CliExitCodes.Success; } private async Task DumpCapabilitiesToDirectoryAsync( @@ -265,77 +200,44 @@ private async Task DumpCapabilitiesToDirectoryAsync( OutputFormat format, CancellationToken cancellationToken) { - var tempDirectory = Directory.CreateTempSubdirectory("aspire-sdk-dump-"); - var tempDir = tempDirectory.FullName; - - try + await using var session = await SdkCommandPreparation.PrepareSessionAsync( + _appHostServerProjectFactory, + _serverSessionFactory, + InteractionService, + _logger, + "aspire-sdk-dump-", + ExecutionContext.IdentityVersion, + integrations, + packageSourceOverride: null, + cancellationToken); + + if (session is null) { - var appHostServerProject = await _appHostServerProjectFactory.CreateAsync(tempDir, cancellationToken); - - _logger.LogDebug("Building AppHost server for batched capability scanning with {Count} integrations", integrations.Count); - - var prepareResult = await appHostServerProject.PrepareAsync( - ExecutionContext.IdentityVersion, - integrations, - cancellationToken: cancellationToken); - - if (!prepareResult.Success) - { - InteractionService.DisplayError("Failed to build capability scanner."); - if (prepareResult.Output is not null) - { - foreach (var (_, line) in prepareResult.Output.GetLines()) - { - InteractionService.DisplayMessage(KnownEmojis.Wrench, line); - } - } - return CliExitCodes.FailedToBuildArtifacts; - } - - await using var serverSession = _serverSessionFactory.Create(appHostServerProject, environmentVariables: null, debug: false, gracefulShutdownSignaler: null, shutdownService: null, isolateConsole: false, cancellationToken); - // Short-lived RPC session: StartAsync() spawns the server. We never observe the - // exit-code task (WaitForExitAsync) because disposal flows the exit code through the - // activity scope and the only failure mode we care about surfaces via the RPC call below. - await serverSession.StartAsync(); - - var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); - outputDirectory.Create(); - - var dumpTasks = integrations - .Select(integration => DumpIntegrationCapabilitiesAsync(rpcClient, integration, outputDirectory, format, cancellationToken)) - .ToArray(); + return CliExitCodes.FailedToBuildArtifacts; + } - var dumpResults = await Task.WhenAll(dumpTasks); - var failures = dumpResults.Where(result => !result.Success).ToArray(); - if (failures.Length > 0) - { - InteractionService.DisplayError("Failed to dump capabilities for one or more integrations."); - foreach (var failure in failures) - { - InteractionService.DisplayMessage(KnownEmojis.CrossMark, $"{failure.IntegrationName}: {failure.ErrorMessage}"); - } + outputDirectory.Create(); - return CliExitCodes.FailedToBuildArtifacts; - } + var dumpTasks = integrations + .Select(integration => DumpIntegrationCapabilitiesAsync(session.RpcClient, integration, outputDirectory, format, cancellationToken)) + .ToArray(); - return dumpResults.Any(result => result.HasErrors) - ? CliExitCodes.InvalidCommand - : CliExitCodes.Success; - } - finally + var dumpResults = await Task.WhenAll(dumpTasks); + var failures = dumpResults.Where(result => !result.Success).ToArray(); + if (failures.Length > 0) { - try + InteractionService.DisplayError("Failed to dump capabilities for one or more integrations."); + foreach (var failure in failures) { - if (Directory.Exists(tempDir)) - { - Directory.Delete(tempDir, recursive: true); - } - } - catch (Exception ex) - { - _logger.LogDebug(ex, "Failed to clean up temp directory {TempDir}", tempDir); + InteractionService.DisplayMessage(KnownEmojis.CrossMark, $"{failure.IntegrationName}: {failure.ErrorMessage}"); } + + return CliExitCodes.FailedToBuildArtifacts; } + + return dumpResults.Any(result => result.HasErrors) + ? CliExitCodes.InvalidCommand + : CliExitCodes.Success; } private async Task DumpIntegrationCapabilitiesAsync( diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs new file mode 100644 index 00000000000..0361986e6d7 --- /dev/null +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -0,0 +1,209 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.CommandLine; +using System.Text.Json; +using Aspire.Cli.Configuration; +using Aspire.Cli.Interaction; +using Aspire.Cli.Projects; +using Microsoft.Extensions.Logging; +using StreamJsonRpc; + +namespace Aspire.Cli.Commands.Sdk; + +/// +/// Command for exporting the canonical API reference of an Aspire package for a target language. +/// +/// Usage: +/// aspire sdk export --language typescript # Core Aspire.Hosting at this CLI's SDK version +/// aspire sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0 +/// +/// +/// The output is consumed by documentation pipelines, so stdout carries exactly one JSON document +/// and nothing else. Every status message, warning, and error goes to stderr, which is what makes +/// aspire sdk export ... > api.json produce a usable file. +/// +internal sealed class SdkExportCommand : BaseCommand +{ + private const string CorePackageName = "Aspire.Hosting"; + + private readonly IAppHostServerProjectFactory _appHostServerProjectFactory; + private readonly IAppHostServerSessionFactory _serverSessionFactory; + private readonly ILogger _logger; + + private static readonly Option s_languageOption = new("--language", "-l") + { + Description = "Target language for the API export (e.g., typescript).", + Required = true + }; + private static readonly Option s_packageOption = new("--package", "-p") + { + Description = "Package to export in PackageName@Version format. Defaults to the core Aspire.Hosting package at this CLI's SDK version." + }; + private static readonly Option s_sourceOption = new("--source", "-s") + { + Description = "NuGet package source to restore the package from." + }; + private static readonly Option s_outputOption = new("--output", "-o") + { + Description = "Output file. If not specified, the document is written to stdout." + }; + + public SdkExportCommand( + IAppHostServerProjectFactory appHostServerProjectFactory, + IAppHostServerSessionFactory serverSessionFactory, + ILogger logger, + CommonCommandServices services) + : base("export", "Export the canonical API reference for an Aspire package in a target language.", services) + { + _appHostServerProjectFactory = appHostServerProjectFactory; + _serverSessionFactory = serverSessionFactory; + _logger = logger; + + Hidden = true; + + Options.Add(s_languageOption); + Options.Add(s_packageOption); + Options.Add(s_sourceOption); + Options.Add(s_outputOption); + } + + protected override async Task ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken) + { + var language = parseResult.GetValue(s_languageOption)!; + var package = parseResult.GetValue(s_packageOption); + var packageSource = parseResult.GetValue(s_sourceOption); + var outputFile = parseResult.GetValue(s_outputOption); + + string packageName; + string packageVersion; + var integrations = new List(); + + if (string.IsNullOrWhiteSpace(package)) + { + // Documentation has to describe the SDK this CLI generates against, so the default is + // the CLI's own identity version rather than whatever the feed currently calls latest. + packageName = CorePackageName; + packageVersion = ExecutionContext.IdentityVersion; + } + else + { + if (!SdkCommandPreparation.TryParseIntegrationArgument( + package, + requireExactVersion: true, + out var reference, + out var errorExitCode, + out var errorMessage)) + { + return CommandResult.Failure(errorExitCode, errorMessage!); + } + + if (reference!.Version is null) + { + return CommandResult.Failure( + CliExitCodes.InvalidCommand, + $"Invalid package '{package}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@13.5.0); project references are not supported by sdk export."); + } + + packageName = reference.Name; + packageVersion = reference.Version; + + // The core package is always restored by the scanner AppHost, so adding it again would + // produce a duplicate package reference. + if (!string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase)) + { + integrations.Add(reference); + } + } + + return CommandResult.FromExitCode(await ExportApiAsync( + language, + packageName, + packageVersion, + integrations, + packageSource, + outputFile, + cancellationToken)); + } + + private async Task ExportApiAsync( + string language, + string packageName, + string packageVersion, + List integrations, + string? packageSource, + FileInfo? outputFile, + CancellationToken cancellationToken) + { + // The AppHost is restored at the version being documented so the export describes that exact + // SDK, not the CLI's bundled one. + var sdkVersion = string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase) + ? packageVersion + : ExecutionContext.IdentityVersion; + + await using var session = await SdkCommandPreparation.PrepareSessionAsync( + _appHostServerProjectFactory, + _serverSessionFactory, + InteractionService, + _logger, + "aspire-sdk-export-", + sdkVersion, + integrations, + packageSource, + cancellationToken); + + if (session is null) + { + return CliExitCodes.FailedToBuildArtifacts; + } + + JsonElement export; + try + { + _logger.LogDebug("Exporting {Language} API reference for {PackageName}@{PackageVersion} via RPC", language, packageName, packageVersion); + export = await session.RpcClient.ExportApiAsync(language, packageName, packageVersion, cancellationToken); + } + catch (RemoteInvocationException ex) + { + InteractionService.DisplayError(ex.Message); + + // An unsupported language is a usage error the caller can fix by choosing another + // language, so it is worth distinguishing from the AppHost genuinely falling over. + return IsUnsupportedLanguage(ex) + ? CliExitCodes.InvalidCommand + : CliExitCodes.FailedToBuildArtifacts; + } + catch (NotSupportedException ex) + { + InteractionService.DisplayError(ex.Message); + return CliExitCodes.InvalidCommand; + } + + // GetRawText is the document exactly as the language provider wrote it. Re-serializing would + // reshape whitespace and property order for no benefit, and the whole contract here is that + // the payload passes through untouched. + var json = export.GetRawText(); + + if (outputFile is not null) + { + var outputDir = outputFile.Directory; + if (outputDir is not null && !outputDir.Exists) + { + outputDir.Create(); + } + + await File.WriteAllTextAsync(outputFile.FullName, json, cancellationToken); + InteractionService.DisplaySuccess($"API reference written to {outputFile.FullName}"); + return CliExitCodes.Success; + } + + InteractionService.DisplayRawText(json, consoleOverride: ConsoleOutput.Standard); + return CliExitCodes.Success; + } + + // RemoteHost raises NotSupportedException for a generator that cannot export; StreamJsonRpc + // flattens that to a message string, so the type name is the only marker that survives the wire. + private static bool IsUnsupportedLanguage(RemoteInvocationException ex) + => ex.Message.Contains("IApiReferenceExporter", StringComparison.Ordinal) + || ex.Message.Contains("No code generator found for language", StringComparison.Ordinal); +} diff --git a/src/Aspire.Cli/Program.cs b/src/Aspire.Cli/Program.cs index 3dc68b889be..0e53283941b 100644 --- a/src/Aspire.Cli/Program.cs +++ b/src/Aspire.Cli/Program.cs @@ -666,6 +666,7 @@ internal static async Task BuildApplicationAsync(string[] args, CliStartu builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddTransient(); diff --git a/src/Aspire.Cli/Projects/AppHostRpcClient.cs b/src/Aspire.Cli/Projects/AppHostRpcClient.cs index 703cb36e2c3..e922d0aa91b 100644 --- a/src/Aspire.Cli/Projects/AppHostRpcClient.cs +++ b/src/Aspire.Cli/Projects/AppHostRpcClient.cs @@ -110,6 +110,10 @@ public Task> GenerateCodeForAssemblyAsync(string lang public Task GetCapabilitiesForAssembliesAsync(IReadOnlyList assemblyNames, CancellationToken cancellationToken) => InvokeCodeGenerationAsync("getCapabilities", [assemblyNames], cancellationToken); + /// + public Task ExportApiAsync(string languageId, string packageName, string packageVersion, CancellationToken cancellationToken) + => InvokeCodeGenerationAsync("exportApi", [languageId, packageName, packageVersion], cancellationToken); + /// public Task InvokeAsync(string methodName, object?[] parameters, CancellationToken cancellationToken) => _jsonRpc.InvokeWithProfilingAsync(_profilingTelemetry, ConnectionName, methodName, parameters, cancellationToken); diff --git a/src/Aspire.Cli/Projects/IAppHostRpcClient.cs b/src/Aspire.Cli/Projects/IAppHostRpcClient.cs index 5051fe95c2d..4cd654282f2 100644 --- a/src/Aspire.Cli/Projects/IAppHostRpcClient.cs +++ b/src/Aspire.Cli/Projects/IAppHostRpcClient.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json; using Aspire.Cli.Commands.Sdk; using Aspire.TypeSystem; @@ -71,6 +72,19 @@ Task> ScaffoldAppHostAsync( /// A token to cancel the operation. Task GetCapabilitiesForAssembliesAsync(IReadOnlyList assemblyNames, CancellationToken cancellationToken); + /// + /// Exports the canonical API reference document for a package in the target language. + /// + /// + /// Calls the exportApi RPC method. The document is language-defined and is returned as raw + /// JSON so the CLI never has to understand or reshape it. + /// + /// The target language identifier. + /// The package to export documentation for. + /// The exact resolved version of the package. + /// A token to cancel the operation. + Task ExportApiAsync(string languageId, string packageName, string packageVersion, CancellationToken cancellationToken); + // ═══════════════════════════════════════════════════════════════ // GENERIC INVOKE (for future/custom calls) // ═══════════════════════════════════════════════════════════════ diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs new file mode 100644 index 00000000000..d1e2ea14786 --- /dev/null +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -0,0 +1,310 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text.Json; +using Aspire.Cli.Commands; +using Aspire.Cli.Configuration; +using Aspire.Cli.Interaction; +using Aspire.Cli.Projects; +using Aspire.Cli.Tests.TestServices; +using Aspire.Cli.Tests.Utils; +using Aspire.Cli.Commands.Sdk; +using Microsoft.AspNetCore.InternalTesting; +using Microsoft.Extensions.DependencyInjection; +using StreamJsonRpc; + +namespace Aspire.Cli.Tests.Commands.Sdk; + +/// +/// Covers aspire sdk export. The command exists to feed documentation pipelines, so the +/// discipline it needs is unusual for a CLI command: stdout has to be exactly one machine-readable +/// document with nothing else mixed in, and the package version has to be exact so published +/// documentation can be keyed on it. +/// +public class SdkExportCommandTests(ITestOutputHelper outputHelper) +{ + [Fact] + public async Task SdkExportWithHelpReturnsZero() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper); + using var provider = services.BuildServiceProvider(); + + var command = provider.GetRequiredService(); + var result = command.Parse("sdk export --help"); + + var exitCode = await result.InvokeAsync().DefaultTimeout(); + + Assert.Equal(0, exitCode); + } + + [Fact] + public async Task SdkExportForExactPackageWritesCanonicalDocumentToStdout() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); + using var _ = workspace; + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("typescript", "Aspire.Hosting.Redis", "13.5.0"), rpcClient.LastExportRequest); + + var stdout = Assert.Single(interactionService.DisplayedRawText, entry => entry.ConsoleOverride == ConsoleOutput.Standard); + using var document = JsonDocument.Parse(stdout.Text); + Assert.Equal(1, document.RootElement.GetProperty("schemaVersion").GetInt32()); + Assert.Equal("Aspire.Hosting.Redis", document.RootElement.GetProperty("package").GetProperty("name").GetString()); + } + + [Fact] + public async Task SdkExportDefaultsToCoreHostingAtTheRunningSdkVersion() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); + using var _ = workspace; + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); + + Assert.Equal(CliExitCodes.Success, exitCode); + + // Defaulting to the CLI's own SDK version is the entire point of the command: documentation + // must describe the SDK this CLI would actually generate against, not a floating latest. + var expectedVersion = provider.GetRequiredService().IdentityVersion; + Assert.Equal(("typescript", "Aspire.Hosting", expectedVersion), rpcClient.LastExportRequest); + } + + [Fact] + public async Task SdkExportSendsProgressToStderrOnly() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out _); + using var _2 = workspace; + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.DoesNotContain( + interactionService.DisplayedMessages, + message => message.ConsoleOverride == ConsoleOutput.Standard); + } + + [Fact] + public async Task SdkExportPassesPackageSourceThroughToPrepare() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); + using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0 --source /tmp/aspire-hive"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal("/tmp/aspire-hive", appHostServerProject.PackageSourceOverride); + } + + [Theory] + [InlineData("Aspire.Hosting")] + [InlineData("Aspire.Hosting@")] + [InlineData("@13.5.0")] + [InlineData("Aspire.Hosting@not-a-version")] + [InlineData("Aspire@Hosting@13.5.0")] + public async Task SdkExportWithMalformedPackageReturnsInvalidCommand(string package) + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out _); + using var _2 = workspace; + + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package \"{package}\""); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Empty(interactionService.DisplayedRawText); + } + + [Theory] + [InlineData("13.5.*")] + [InlineData("[13.5.0,14.0.0)")] + [InlineData("13.5.0-*")] + public async Task SdkExportWithFloatingVersionReturnsInvalidCommand(string version) + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out _); + using var _2 = workspace; + + // Floating versions are rejected before restore rather than resolved, because a document + // published under a range would silently describe a different SDK on the next restore. + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package \"Aspire.Hosting@{version}\""); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Empty(interactionService.DisplayedRawText); + } + + [Fact] + public async Task SdkExportWithUnsupportedLanguageReturnsInvalidCommand() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out _, new ThrowingExportRpcClient( + new NotSupportedException("The 'Go' code generator does not implement IApiReferenceExporter."))); + using var _2 = workspace; + + var exitCode = await InvokeAsync(provider, "sdk export --language go --package Aspire.Hosting@13.5.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Empty(interactionService.DisplayedRawText); + } + + [Fact] + public async Task SdkExportWhenRpcFailsReturnsFailureAndWritesNothingToStdout() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out _, new ThrowingExportRpcClient( + new RemoteInvocationException("apphost blew up", 0, errorData: null))); + using var _2 = workspace; + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0"); + + Assert.NotEqual(CliExitCodes.Success, exitCode); + + // A partial document is worse than none: a consumer would publish it as if it were complete. + Assert.Empty(interactionService.DisplayedRawText); + } + + [Fact] + public async Task SdkDumpJsonPayloadIsUnchangedByTheSharedPreparationExtraction() + { + // sdk export and sdk dump now share preparation code but nothing else. This lives beside the + // export tests because it guards the extraction, not dump's own behaviour: dump must keep + // producing its existing capabilities payload and must not be routed through the canonical + // exporter. + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var rpcClient = new CapabilitiesRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName)); + + var exitCode = await InvokeAsync(provider, "sdk dump --format json Aspire.Hosting.Redis@13.5.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(["Aspire.Hosting.Redis"], rpcClient.LastAssemblyNames); + + var stdout = Assert.Single(interactionService.DisplayedRawText); + using var document = JsonDocument.Parse(stdout.Text); + + // The capabilities shape, not the canonical export schema. + Assert.False(document.RootElement.TryGetProperty("schemaVersion", out _)); + Assert.True(document.RootElement.TryGetProperty("Capabilities", out _)); + } + + private static async Task InvokeAsync(ServiceProvider provider, string commandLine) + { + var command = provider.GetRequiredService(); + return await command.Parse(commandLine).InvokeAsync().DefaultTimeout(); + } + + private ServiceProvider CreateProvider( + TestInteractionService interactionService, + out TemporaryWorkspace workspace, + out StubExportRpcClient rpcClient, + IAppHostRpcClient? overrideRpcClient = null) + { + workspace = TemporaryWorkspace.CreateForCli(outputHelper); + rpcClient = new StubExportRpcClient(); + return CreateProvider( + interactionService, + workspace, + overrideRpcClient ?? rpcClient, + new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName)); + } + + private ServiceProvider CreateProvider( + TestInteractionService interactionService, + TemporaryWorkspace workspace, + IAppHostRpcClient rpcClient, + IAppHostServerProject appHostServerProject) + { + var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper, options => + { + options.InteractionServiceFactory = _ => interactionService; + }); + + services.AddSingleton(new TestAppHostServerProjectFactory + { + CreateAsyncCallback = (_, _) => Task.FromResult(appHostServerProject) + }); + services.AddSingleton(new FakeAppHostServerSessionFactory + { + Session = new FakeAppHostServerSession(rpcClient) + }); + + return services.BuildServiceProvider(); + } + + private sealed class StubExportRpcClient : FakeAppHostRpcClient + { + public (string Language, string PackageName, string PackageVersion)? LastExportRequest { get; private set; } + + public override Task ExportApiAsync(string languageId, string packageName, string packageVersion, CancellationToken cancellationToken) + { + LastExportRequest = (languageId, packageName, packageVersion); + + using var document = JsonDocument.Parse($$""" + { + "schemaVersion": 1, + "language": "{{languageId}}", + "package": { "name": "{{packageName}}", "version": "{{packageVersion}}" }, + "modules": [], + "declarations": [] + } + """); + + return Task.FromResult(document.RootElement.Clone()); + } + } + + private sealed class ThrowingExportRpcClient(Exception exception) : FakeAppHostRpcClient + { + public override Task ExportApiAsync(string languageId, string packageName, string packageVersion, CancellationToken cancellationToken) + => Task.FromException(exception); + } + + private sealed class CapabilitiesRpcClient : FakeAppHostRpcClient + { + public IReadOnlyList? LastAssemblyNames { get; private set; } + + public override Task GetCapabilitiesForAssembliesAsync(IReadOnlyList assemblyNames, CancellationToken cancellationToken) + { + LastAssemblyNames = assemblyNames; + return Task.FromResult(new CapabilitiesInfo()); + } + } + + private sealed class CapturingAppHostServerProject(string appDirectoryPath) : IAppHostServerProject + { + public string AppDirectoryPath { get; } = appDirectoryPath; + + public string? PackageSourceOverride { get; private set; } + + public string GetInstanceIdentifier() => AppDirectoryPath; + + public Task PrepareAsync( + string sdkVersion, + IEnumerable integrations, + string? requestedChannel = null, + string? packageSourceOverride = null, + CancellationToken cancellationToken = default) + { + PackageSourceOverride = packageSourceOverride; + return Task.FromResult(new AppHostServerPrepareResult(Success: true, Output: null)); + } + + public Task RunAsync( + int hostPid, + IReadOnlyDictionary? environmentVariables, + string[]? additionalArgs, + bool debug, + AppHostServerRunControl? runControl) + => throw new NotSupportedException("Run should not be invoked when using a fake codegen session."); + } +} diff --git a/tests/Aspire.Cli.Tests/TestServices/FakeAppHostServerSession.cs b/tests/Aspire.Cli.Tests/TestServices/FakeAppHostServerSession.cs index ba04b428997..1e98e47dc5e 100644 --- a/tests/Aspire.Cli.Tests/TestServices/FakeAppHostServerSession.cs +++ b/tests/Aspire.Cli.Tests/TestServices/FakeAppHostServerSession.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json; using Aspire.Cli.Commands.Sdk; using Aspire.Cli.Processes; using Aspire.Cli.Projects; @@ -101,10 +102,11 @@ public IAppHostServerSession Create( /// /// Fake RPC client that returns empty results for all operations. /// Used to exercise code paths that run after RPC connection without needing a real server. +/// Members are virtual so a test can override just the call it exercises. /// -internal sealed class FakeAppHostRpcClient : IAppHostRpcClient +internal class FakeAppHostRpcClient : IAppHostRpcClient { - public Task GetRuntimeSpecAsync(string languageId, CancellationToken cancellationToken) + public virtual Task GetRuntimeSpecAsync(string languageId, CancellationToken cancellationToken) => Task.FromResult(new RuntimeSpec { Language = languageId, @@ -114,25 +116,28 @@ public Task GetRuntimeSpecAsync(string languageId, CancellationToke Execute = new CommandSpec { Command = "node", Args = ["apphost.js"] } }); - public Task> ScaffoldAppHostAsync(string languageId, string targetPath, string? projectName, CancellationToken cancellationToken) + public virtual Task> ScaffoldAppHostAsync(string languageId, string targetPath, string? projectName, CancellationToken cancellationToken) => throw new NotSupportedException(); - public Task> GenerateCodeAsync(string languageId, CancellationToken cancellationToken) + public virtual Task> GenerateCodeAsync(string languageId, CancellationToken cancellationToken) => Task.FromResult(new Dictionary()); - public Task> GenerateCodeForAssemblyAsync(string languageId, string assemblyName, CancellationToken cancellationToken) + public virtual Task> GenerateCodeForAssemblyAsync(string languageId, string assemblyName, CancellationToken cancellationToken) => Task.FromResult(new Dictionary()); - public Task GetCapabilitiesAsync(CancellationToken cancellationToken) + public virtual Task GetCapabilitiesAsync(CancellationToken cancellationToken) => throw new NotSupportedException(); - public Task GetCapabilitiesForAssembliesAsync(IReadOnlyList assemblyNames, CancellationToken cancellationToken) + public virtual Task GetCapabilitiesForAssembliesAsync(IReadOnlyList assemblyNames, CancellationToken cancellationToken) => throw new NotSupportedException(); - public Task InvokeAsync(string methodName, object?[] parameters, CancellationToken cancellationToken) + public virtual Task ExportApiAsync(string languageId, string packageName, string packageVersion, CancellationToken cancellationToken) => throw new NotSupportedException(); - public Task InvokeAsync(string methodName, object?[] parameters, CancellationToken cancellationToken) + public virtual Task InvokeAsync(string methodName, object?[] parameters, CancellationToken cancellationToken) + => throw new NotSupportedException(); + + public virtual Task InvokeAsync(string methodName, object?[] parameters, CancellationToken cancellationToken) => throw new NotSupportedException(); public ValueTask DisposeAsync() => ValueTask.CompletedTask; diff --git a/tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs b/tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs index aea5aa4edcb..00f99169d02 100644 --- a/tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs +++ b/tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs @@ -296,6 +296,7 @@ public static IServiceCollection CreateServiceCollection(TemporaryWorkspace work services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); From 8f6ea4aed3aa7afbd66b36ed2a14c6150e63ab1c Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 17:42:42 -0400 Subject: [PATCH 04/73] Make exported declaration fragments self-contained The export contract promises that concatenating a manifest's declaration fragments type-checks without site-authored shims. Running TypeScript over real Aspire.Hosting and Aspire.Hosting.Redis exports showed it did not. Handle types with no generated wrapper class surface in signatures under their raw handle alias name, but the fragment pass derived a class name instead, so it declared a symbol nothing referenced and left the referenced alias undefined. Emit the same alias the generator emits. The runtime fragment was also missing Handle, InputType and AbortSignal, and MarshalledHandle was missing $type. Keep sdk export's own --help reachable: Hidden on a subcommand suppresses its help output, and the parent sdk command is already hidden. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../Commands/Sdk/SdkExportCommand.cs | 4 +- .../TypeScriptApiProjector.cs | 40 +++++-- .../AtsTypeScriptCodeGeneratorTests.cs | 112 +++++++++++++++++- ...eneratorTests.ApiDeclarations.verified.txt | 11 +- ...CodeGeneratorTests.ApiExport.verified.json | 12 +- 5 files changed, 167 insertions(+), 12 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 0361986e6d7..4d8145dc6c1 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -60,8 +60,8 @@ public SdkExportCommand( _serverSessionFactory = serverSessionFactory; _logger = logger; - Hidden = true; - + // Not marked Hidden: the parent `sdk` command already hides the whole subtree, and setting + // Hidden here additionally suppresses this command's own --help output. Options.Add(s_languageOption); Options.Add(s_packageOption); Options.Add(s_sourceOption); diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index db87397d7e7..c966345c825 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -43,16 +43,19 @@ internal sealed partial class TypeScriptApiProjector /// The symbol names already declares. private static readonly HashSet s_runtimeDeclaredNames = new(StringComparer.Ordinal) { - "Awaitable", "MarshalledHandle", "HandleReference", "CancellationToken", "ReferenceExpression", - "AspireList", "AspireDict", "ResourceBuilderBase", "InteractionInput", - "InteractionInputCollection", "InteractionInputCollectionPromise" + "Awaitable", "MarshalledHandle", "Handle", "HandleReference", "AbortSignal", "CancellationToken", + "ReferenceExpression", "AspireList", "AspireDict", "ResourceBuilderBase", "InputType", + "InteractionInput", "InteractionInputCollection", "InteractionInputCollectionPromise" }; private const string RuntimeDeclarationContent = """ export type Awaitable = T | PromiseLike; - export interface MarshalledHandle { $handle: string; } + export interface MarshalledHandle { $handle: string; $type: string; } + export interface Handle { readonly $handle: string; readonly $type: T; toJSON(): MarshalledHandle; } export interface HandleReference { toJSON(): MarshalledHandle; } + export interface AbortSignal { readonly aborted: boolean; } export interface CancellationToken { readonly aborted: boolean; } + export enum InputType { Text = 'Text', SecretText = 'SecretText', Choice = 'Choice', Boolean = 'Boolean', Number = 'Number' } export interface ReferenceExpression { readonly value: Promise; } export interface AspireList extends HandleReference { get(index: number): Promise; } export interface AspireDict extends HandleReference { get(key: TKey): Promise; } @@ -462,7 +465,31 @@ internal TypeScriptApiModel BuildApiModel( foreach (var typeId in _resolved.HandleTypeIds.OrderBy(id => id, StringComparer.Ordinal)) { - var name = GetInterfaceName(_wrapperClassNames.GetValueOrDefault(typeId) ?? DeriveClassName(typeId)); + var wrapperClassName = _wrapperClassNames.GetValueOrDefault(typeId); + var owningAssembly = GetTypeOwningAssemblyName(typeId); + + // Handle types without a generated wrapper class surface in signatures under their raw + // handle alias name, so the fragment has to declare that exact alias. Deriving a class + // name here instead would declare a symbol no signature ever references and leave the + // referenced one undefined. + if (wrapperClassName is null) + { + var handleName = GetHandleTypeName(typeId); + + if (declaredNames.Add(handleName)) + { + declarations[$"{owningAssembly}:handle:{handleName}"] = new TypeScriptApiDeclaration + { + Id = $"{owningAssembly}:handle:{handleName}", + Content = $"export type {handleName} = Handle<'{typeId}'>;", + OwningAssemblyName = owningAssembly + }; + } + + continue; + } + + var name = GetInterfaceName(wrapperClassName); if (!declaredNames.Add(name)) { @@ -472,7 +499,6 @@ internal TypeScriptApiModel BuildApiModel( var baseType = _typeRefsById.GetValueOrDefault(typeId)?.IsResourceBuilder == true ? "ResourceBuilderBase" : "HandleReference"; - var owningAssembly = GetTypeOwningAssemblyName(typeId); declarations[$"{owningAssembly}:opaque:{name}"] = new TypeScriptApiDeclaration { @@ -486,7 +512,7 @@ internal TypeScriptApiModel BuildApiModel( continue; } - var promiseName = GetPromiseInterfaceName(_wrapperClassNames.GetValueOrDefault(typeId) ?? DeriveClassName(typeId)); + var promiseName = GetPromiseInterfaceName(wrapperClassName); if (!declaredNames.Add(promiseName)) { continue; diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index bdebf11ab46..c3788472d15 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -15,7 +15,7 @@ namespace Aspire.Hosting.CodeGeneration.TypeScript.Tests; -public class AtsTypeScriptCodeGeneratorTests +public partial class AtsTypeScriptCodeGeneratorTests { private readonly AtsTypeScriptCodeGenerator _generator = new(); @@ -1924,6 +1924,116 @@ await Verify(declarations, extension: "txt") .UseFileName("AtsTypeScriptCodeGeneratorTests.ApiDeclarations"); } + /// + /// The export contract promises that concatenating a manifest's declaration fragments type-checks + /// without site-authored shims, so every symbol a fragment names must be declared by some fragment. + /// This caught a real gap: handle types with no wrapper class surface in signatures under their raw + /// XHandle alias, but the fragment pass derived a different name and declared nothing. + /// + [Fact] + public void ApiExportDeclarationFragmentsReferenceOnlyDeclaredOrBuiltInSymbols() + { + var atsContext = CreateOwnershipFilteredContext(); + + var projector = new TypeScriptApiProjector(atsContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var declaredNames = new HashSet(StringComparer.Ordinal); + + foreach (var declaration in model.Declarations) + { + foreach (Match match in DeclaredNameRegex().Matches(declaration.Content)) + { + declaredNames.Add(match.Groups[1].Value); + } + } + + var referenced = new HashSet(StringComparer.Ordinal); + + foreach (var declaration in model.Declarations) + { + foreach (var name in ExtractReferencedTypeNames(declaration.Content)) + { + referenced.Add(name); + } + } + + // Rendered item and member signatures are scanned too: they name the same symbols the + // fragments must supply, and they are where an alias the fragments never declared shows up. + // Enum items are excluded: their members are value names declared by the enum itself, not + // references to other symbols. + foreach (var item in model.Modules + .SelectMany(module => module.Items) + .Where(item => item.Kind != TypeScriptApiItemKind.Enum)) + { + var signatures = item.Members + .Select(member => member.Declaration) + .Append(item.Declaration) + .Concat(item.Extends); + + foreach (var name in signatures.SelectMany(ExtractReferencedTypeNames)) + { + referenced.Add(name); + } + } + + referenced.ExceptWith(declaredNames); + referenced.ExceptWith(s_typeScriptBuiltInNames); + + Assert.True( + referenced.Count == 0, + $"Declaration fragments reference undeclared symbols: {string.Join(", ", referenced.OrderBy(name => name, StringComparer.Ordinal))}"); + } + + /// + /// TypeScript symbols the language itself provides, so fragments may reference them without + /// declaring them. + /// + private static readonly HashSet s_typeScriptBuiltInNames = new(StringComparer.Ordinal) + { + "Promise", "PromiseLike", "Record", "Partial", "Readonly", "Array", "Function", "Date", "Error" + }; + + /// + /// Collects the type names a declaration fragment references. Enum bodies are dropped first because + /// their members are declared by the enum itself, then string literals are removed so that handle + /// aliases such as export type XHandle = Handle<'Assembly/Namespace.Type'>; do not look + /// like type references. + /// + private static IEnumerable ExtractReferencedTypeNames(string content) + { + var withoutEnums = EnumDeclarationRegex().Replace(content, string.Empty); + var withoutLiterals = StringLiteralRegex().Replace(withoutEnums, "\"\""); + + foreach (Match match in IdentifierRegex().Matches(withoutLiterals)) + { + var name = match.Value; + + // Conventional generic parameter names (T, TKey, TValue) are introduced by the + // declaration that uses them, so they are never resolved against other fragments. + if (name is "T" || (name.Length > 1 && name[0] == 'T' && char.IsUpper(name[1]))) + { + continue; + } + + yield return name; + } + } + + [GeneratedRegex(@"^export (?:interface|enum|type) (\w+)", RegexOptions.Multiline)] + private static partial Regex DeclaredNameRegex(); + + [GeneratedRegex(@"enum \w+ \{[^}]*\}")] + private static partial Regex EnumDeclarationRegex(); + + [GeneratedRegex(@"'[^']*'|""[^""]*""")] + private static partial Regex StringLiteralRegex(); + + [GeneratedRegex(@"\b[A-Z][A-Za-z0-9_]*\b")] + private static partial Regex IdentifierRegex(); + [Fact] public void ApiExportDeclarationsAppearInGeneratedPublicInterfaces() { diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index 64715c97594..7627efd9a44 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -559,6 +559,9 @@ export enum TestResourceStatus { Failed = "Failed", } +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:handle:ITestVaultResourceHandle +export type ITestVaultResourceHandle = Handle<'Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.ITestVaultResource'>; + // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCallbackContext export interface TestCallbackContext { toJSON(): MarshalledHandle; @@ -865,6 +868,9 @@ export interface WithPersistenceOptions { mode?: TestPersistenceMode; } +// Aspire.Hosting:handle:ReferenceExpressionHandle +export type ReferenceExpressionHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.ReferenceExpression'>; + // Aspire.Hosting:opaque:CSharpAppResource export interface CSharpAppResource extends ResourceBuilderBase {} @@ -939,9 +945,12 @@ export interface ResourceWithEnvironmentPromise extends PromiseLike = T | PromiseLike; -export interface MarshalledHandle { $handle: string; } +export interface MarshalledHandle { $handle: string; $type: string; } +export interface Handle { readonly $handle: string; readonly $type: T; toJSON(): MarshalledHandle; } export interface HandleReference { toJSON(): MarshalledHandle; } +export interface AbortSignal { readonly aborted: boolean; } export interface CancellationToken { readonly aborted: boolean; } +export enum InputType { Text = 'Text', SecretText = 'SecretText', Choice = 'Choice', Boolean = 'Boolean', Number = 'Number' } export interface ReferenceExpression { readonly value: Promise; } export interface AspireList extends HandleReference { get(index: number): Promise; } export interface AspireDict extends HandleReference { get(key: TKey): Promise; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index 851dc285b99..c69fe44b7c3 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -6690,6 +6690,11 @@ "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", "content": "export enum TestResourceStatus {\n Pending = \u0022Pending\u0022,\n Running = \u0022Running\u0022,\n Stopped = \u0022Stopped\u0022,\n Failed = \u0022Failed\u0022,\n}" }, + { + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:handle:ITestVaultResourceHandle", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "content": "export type ITestVaultResourceHandle = Handle\u003C\u0027Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.ITestVaultResource\u0027\u003E;" + }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCallbackContext", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", @@ -6805,6 +6810,11 @@ "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", "content": "export interface WithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" }, + { + "id": "Aspire.Hosting:handle:ReferenceExpressionHandle", + "owningAssembly": "Aspire.Hosting", + "content": "export type ReferenceExpressionHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.ReferenceExpression\u0027\u003E;" + }, { "id": "Aspire.Hosting:opaque:CSharpAppResource", "owningAssembly": "Aspire.Hosting", @@ -6928,7 +6938,7 @@ { "id": "aspire:runtime:base", "owningAssembly": "Aspire.Hosting", - "content": "export type Awaitable\u003CT\u003E = T | PromiseLike\u003CT\u003E;\nexport interface MarshalledHandle { $handle: string; }\nexport interface HandleReference { toJSON(): MarshalledHandle; }\nexport interface CancellationToken { readonly aborted: boolean; }\nexport interface ReferenceExpression { readonly value: Promise\u003Cstring\u003E; }\nexport interface AspireList\u003CT\u003E extends HandleReference { get(index: number): Promise\u003CT\u003E; }\nexport interface AspireDict\u003CTKey, TValue\u003E extends HandleReference { get(key: TKey): Promise\u003CTValue\u003E; }\nexport interface ResourceBuilderBase extends HandleReference {}\nexport interface InteractionInput { readonly name: string; }\nexport interface InteractionInputCollection extends HandleReference {}\nexport interface InteractionInputCollectionPromise extends PromiseLike\u003CInteractionInputCollection\u003E {}" + "content": "export type Awaitable\u003CT\u003E = T | PromiseLike\u003CT\u003E;\nexport interface MarshalledHandle { $handle: string; $type: string; }\nexport interface Handle\u003CT extends string = string\u003E { readonly $handle: string; readonly $type: T; toJSON(): MarshalledHandle; }\nexport interface HandleReference { toJSON(): MarshalledHandle; }\nexport interface AbortSignal { readonly aborted: boolean; }\nexport interface CancellationToken { readonly aborted: boolean; }\nexport enum InputType { Text = \u0027Text\u0027, SecretText = \u0027SecretText\u0027, Choice = \u0027Choice\u0027, Boolean = \u0027Boolean\u0027, Number = \u0027Number\u0027 }\nexport interface ReferenceExpression { readonly value: Promise\u003Cstring\u003E; }\nexport interface AspireList\u003CT\u003E extends HandleReference { get(index: number): Promise\u003CT\u003E; }\nexport interface AspireDict\u003CTKey, TValue\u003E extends HandleReference { get(key: TKey): Promise\u003CTValue\u003E; }\nexport interface ResourceBuilderBase extends HandleReference {}\nexport interface InteractionInput { readonly name: string; }\nexport interface InteractionInputCollection extends HandleReference {}\nexport interface InteractionInputCollectionPromise extends PromiseLike\u003CInteractionInputCollection\u003E {}" } ] } \ No newline at end of file From bb015af02e75245db87b2f935e8a8d875677582e Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 17:51:25 -0400 Subject: [PATCH 05/73] Reference the code generation package from sdk export The scanner AppHost does not reference the language's code generation package by default, so the server loaded no generators and every export failed with "No code generator found for language: typescript". sdk generate already adds the package for exactly this reason. Verified end to end against the repo-local AppHost server: exporting Aspire.Hosting and Aspire.Hosting.Redis now writes schema version 1 documents to stdout with nothing on stderr, and TypeScript type-checks their combined declaration fragments with no errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../Commands/Sdk/SdkExportCommand.cs | 41 +++++++++++++++++++ .../Commands/Sdk/SdkExportCommandTests.cs | 24 +++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 4d8145dc6c1..62df25e8648 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -29,6 +29,7 @@ internal sealed class SdkExportCommand : BaseCommand private readonly IAppHostServerProjectFactory _appHostServerProjectFactory; private readonly IAppHostServerSessionFactory _serverSessionFactory; + private readonly ILanguageDiscovery _languageDiscovery; private readonly ILogger _logger; private static readonly Option s_languageOption = new("--language", "-l") @@ -52,12 +53,14 @@ internal sealed class SdkExportCommand : BaseCommand public SdkExportCommand( IAppHostServerProjectFactory appHostServerProjectFactory, IAppHostServerSessionFactory serverSessionFactory, + ILanguageDiscovery languageDiscovery, ILogger logger, CommonCommandServices services) : base("export", "Export the canonical API reference for an Aspire package in a target language.", services) { _appHostServerProjectFactory = appHostServerProjectFactory; _serverSessionFactory = serverSessionFactory; + _languageDiscovery = languageDiscovery; _logger = logger; // Not marked Hidden: the parent `sdk` command already hides the whole subtree, and setting @@ -116,6 +119,15 @@ protected override async Task ExecuteAsync(ParseResult parseResul } } + // The code generator lives in a separate package that the scanner AppHost does not reference + // by default, so without this the server loads no generators and every export fails with + // "No code generator found". `sdk generate` adds the same package for the same reason. + var codeGenPackage = await GetCodeGenerationPackageAsync(language, cancellationToken); + if (codeGenPackage is not null) + { + integrations.Add(IntegrationReference.FromPackage(codeGenPackage, ExecutionContext.IdentityVersion)); + } + return CommandResult.FromExitCode(await ExportApiAsync( language, packageName, @@ -126,6 +138,35 @@ protected override async Task ExecuteAsync(ParseResult parseResul cancellationToken)); } + /// + /// Resolves the code generation package that provides the requested language, matching the way + /// sdk generate resolves it. Returns when the language is unknown so + /// that the server produces the authoritative unsupported-language error. + /// + private async Task GetCodeGenerationPackageAsync(string language, CancellationToken cancellationToken) + { + try + { + var languages = await _languageDiscovery.GetAvailableLanguagesAsync(cancellationToken); + + var languageInfo = languages.FirstOrDefault(l => + l.LanguageId.Value.StartsWith(language, StringComparison.OrdinalIgnoreCase) || + l.CodeGenerator.Equals(language, StringComparison.OrdinalIgnoreCase)); + + if (languageInfo is null) + { + return null; + } + + return await _languageDiscovery.GetPackageForLanguageAsync(languageInfo.LanguageId, cancellationToken); + } + catch (Exception ex) when (ex is not OperationCanceledException) + { + _logger.LogDebug(ex, "Failed to resolve the code generation package for language {Language}", language); + return null; + } + } + private async Task ExportApiAsync( string language, string packageName, diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index d1e2ea14786..1a3b540fdc7 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -102,6 +102,27 @@ public async Task SdkExportPassesPackageSourceThroughToPrepare() Assert.Equal("/tmp/aspire-hive", appHostServerProject.PackageSourceOverride); } + /// + /// The code generator ships in its own package that the scanner AppHost does not reference by + /// default. Without adding it the server loads no generators and every export fails with + /// "No code generator found", which is exactly how this regressed once already. + /// + [Fact] + public async Task SdkExportAddsTheCodeGenerationPackageForTheRequestedLanguage() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); + using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Contains( + appHostServerProject.Integrations, + integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); + } + [Theory] [InlineData("Aspire.Hosting")] [InlineData("Aspire.Hosting@")] @@ -286,6 +307,8 @@ private sealed class CapturingAppHostServerProject(string appDirectoryPath) : IA public string? PackageSourceOverride { get; private set; } + public IReadOnlyList Integrations { get; private set; } = []; + public string GetInstanceIdentifier() => AppDirectoryPath; public Task PrepareAsync( @@ -296,6 +319,7 @@ public Task PrepareAsync( CancellationToken cancellationToken = default) { PackageSourceOverride = packageSourceOverride; + Integrations = [.. integrations]; return Task.FromResult(new AppHostServerPrepareResult(Success: true, Output: null)); } From 529d9b9c7d0822fa68c886f9926b0692a099b398 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 18:10:39 -0400 Subject: [PATCH 06/73] Stop augmentations from claiming another package's type A package that extends a type another package owns emitted its contribution as a normal interface item: same "interface:{name}" stable ID as the owning package's item, and owningAssembly pointing at the extending package. Across a manifest that collides with the real page and misattributes the type, which the export contract explicitly forbids. Give these items an augmentation kind, an "augmentation:{name}" ID, and the type's real owning assembly. The declaration fragments already used this split; the items now match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../TypeScriptApiExportWriter.cs | 1 + .../TypeScriptApiModel.cs | 6 + .../TypeScriptApiProjector.cs | 16 +- .../AtsTypeScriptCodeGeneratorTests.cs | 14 +- ...CodeGeneratorTests.ApiExport.verified.json | 406 +++++++++--------- .../CodeGeneration/ApiReferenceExportTests.cs | 20 +- 6 files changed, 252 insertions(+), 211 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs index c2527ca29cd..b5e1fe08db5 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs @@ -157,6 +157,7 @@ private static JsonObject WriteMember(TypeScriptApiMember member) TypeScriptApiItemKind.Enum => "enum", TypeScriptApiItemKind.Dto => "dto", TypeScriptApiItemKind.Options => "options", + TypeScriptApiItemKind.Augmentation => "augmentation", TypeScriptApiItemKind.Method => "method", TypeScriptApiItemKind.Property => "property", _ => throw new ArgumentOutOfRangeException(nameof(kind), kind, "Unknown API item kind.") diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs index 87dbc8d91d2..12395692f19 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs @@ -22,6 +22,12 @@ internal enum TypeScriptApiItemKind /// A generated options bag interface for a method's optional parameters. Options, + /// + /// The members this package contributes to an interface another package owns. The owning package + /// publishes the type itself, so this is deliberately not a second page for that type. + /// + Augmentation, + /// A method on a generated interface, or a module-level entry point function. Method, diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index c966345c825..224012d8233 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -617,7 +617,7 @@ internal TypeScriptApiModel BuildApiModel( }); } - return (BuildInterfaceItem(builderModel, interfaceName, extends, typeOwner, documentation, members), declarations); + return (BuildInterfaceItem(builderModel, interfaceName, extends, typeOwner, documentation, members, TypeScriptApiItemKind.Interface), declarations); } // The referenced type gets an opaque stub keyed by its real owner so every package that @@ -665,7 +665,10 @@ internal TypeScriptApiModel BuildApiModel( }); } - return (BuildInterfaceItem(builderModel, interfaceName, extends, package.Name, documentation, contributedMembers), declarations); + // The item carries the real owner and a distinct ID: the owning package already publishes a + // page for this type, and reusing "interface:{name}" here would collide with it across a + // manifest and claim the type belongs to whichever package happened to extend it. + return (BuildInterfaceItem(builderModel, interfaceName, extends, typeOwner, documentation, contributedMembers, TypeScriptApiItemKind.Augmentation), declarations); } private static TypeScriptApiItem BuildInterfaceItem( @@ -674,12 +677,15 @@ private static TypeScriptApiItem BuildInterfaceItem( string[] extends, string owningAssemblyName, AtsDocumentationInfo? documentation, - List members) + List members, + TypeScriptApiItemKind kind) => new() { - Id = $"interface:{interfaceName}", + Id = kind == TypeScriptApiItemKind.Augmentation + ? $"augmentation:{interfaceName}" + : $"interface:{interfaceName}", TypeId = builderModel.TypeId, - Kind = TypeScriptApiItemKind.Interface, + Kind = kind, Name = interfaceName, Declaration = BuildInterfaceHeader(interfaceName, extends), OwningAssemblyName = owningAssemblyName, diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index c3788472d15..b81223cb18b 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2095,9 +2095,21 @@ public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() Assert.All(documentedItems, item => Assert.True( item.TypeId.StartsWith($"{TestPackageName}/", StringComparison.Ordinal) || - item.OwningAssemblyName == TestPackageName, + item.OwningAssemblyName == TestPackageName || + item.Kind == TypeScriptApiItemKind.Augmentation, $"Item '{item.Id}' ({item.TypeId}) is neither package-owned nor a package contribution.")); + // A package that extends another package's type must not publish a second page for it. The + // owning package's export uses "interface:{name}" for that type, so an augmentation reusing + // that ID would collide across a manifest and claim ownership it does not have. + Assert.All( + documentedItems.Where(item => item.Kind == TypeScriptApiItemKind.Augmentation), + item => + { + Assert.StartsWith("augmentation:", item.Id, StringComparison.Ordinal); + Assert.NotEqual(TestPackageName, item.OwningAssemblyName); + }); + // Members are owned per capability, so no documented member may come from another assembly. Assert.All( documentedItems.SelectMany(item => item.Members), diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index c69fe44b7c3..5e830233b87 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -10,178 +10,11 @@ "name": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", "items": [ { - "id": "dto:TestConfigDto", - "kind": "dto", - "name": "TestConfigDto", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestConfigDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestConfigDto", - "summary": "Test DTO to verify [AspireDto] generates TypeScript interfaces.", - "members": [ - { - "id": "property:TestConfigDto.name", - "kind": "property", - "name": "name", - "declaration": "name?: string", - "summary": "The name of the test config." - }, - { - "id": "property:TestConfigDto.port", - "kind": "property", - "name": "port", - "declaration": "port?: number", - "summary": "The port used by the test config." - }, - { - "id": "property:TestConfigDto.enabled", - "kind": "property", - "name": "enabled", - "declaration": "enabled?: boolean", - "summary": "A value indicating whether the test config is enabled." - }, - { - "id": "property:TestConfigDto.optionalField", - "kind": "property", - "name": "optionalField", - "declaration": "optionalField?: string | null", - "summary": "An optional test config field." - } - ] - }, - { - "id": "dto:TestDeeplyNestedDto", - "kind": "dto", - "name": "TestDeeplyNestedDto", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestDeeplyNestedDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestDeeplyNestedDto", - "summary": "Test DTO with deeply nested generic types.", - "members": [ - { - "id": "property:TestDeeplyNestedDto.nestedData", - "kind": "property", - "name": "nestedData", - "declaration": "nestedData?: Record\u003Cstring, TestConfigDto[]\u003E", - "summary": "Deeply nested generic: Dictionary containing List of DTOs." - }, - { - "id": "property:TestDeeplyNestedDto.metadataArray", - "kind": "property", - "name": "metadataArray", - "declaration": "metadataArray?: Record\u003Cstring, string\u003E[]", - "summary": "Array of dictionaries." - } - ] - }, - { - "id": "dto:TestNestedDto", - "kind": "dto", - "name": "TestNestedDto", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestNestedDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestNestedDto", - "summary": "Test DTO with complex nested types.", - "members": [ - { - "id": "property:TestNestedDto.id", - "kind": "property", - "name": "id", - "declaration": "id?: string" - }, - { - "id": "property:TestNestedDto.config", - "kind": "property", - "name": "config", - "declaration": "config?: TestConfigDto" - }, - { - "id": "property:TestNestedDto.tags", - "kind": "property", - "name": "tags", - "declaration": "tags?: string[]" - }, - { - "id": "property:TestNestedDto.counts", - "kind": "property", - "name": "counts", - "declaration": "counts?: Record\u003Cstring, number\u003E" - } - ] - }, - { - "id": "enum:TestPersistenceMode", - "kind": "enum", - "name": "TestPersistenceMode", - "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestPersistenceMode", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export enum TestPersistenceMode", - "summary": "Test persistence mode enum.", - "members": [ - { - "id": "enumValue:TestPersistenceMode.None", - "kind": "property", - "name": "None", - "declaration": "None = \u0022None\u0022" - }, - { - "id": "enumValue:TestPersistenceMode.Volume", - "kind": "property", - "name": "Volume", - "declaration": "Volume = \u0022Volume\u0022" - }, - { - "id": "enumValue:TestPersistenceMode.Bind", - "kind": "property", - "name": "Bind", - "declaration": "Bind = \u0022Bind\u0022" - } - ] - }, - { - "id": "enum:TestResourceStatus", - "kind": "enum", - "name": "TestResourceStatus", - "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestResourceStatus", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export enum TestResourceStatus", - "summary": "Test enum for type generation verification.", - "members": [ - { - "id": "enumValue:TestResourceStatus.Pending", - "kind": "property", - "name": "Pending", - "declaration": "Pending = \u0022Pending\u0022", - "summary": "The resource is pending." - }, - { - "id": "enumValue:TestResourceStatus.Running", - "kind": "property", - "name": "Running", - "declaration": "Running = \u0022Running\u0022", - "summary": "The resource is running." - }, - { - "id": "enumValue:TestResourceStatus.Stopped", - "kind": "property", - "name": "Stopped", - "declaration": "Stopped = \u0022Stopped\u0022", - "summary": "The resource is stopped." - }, - { - "id": "enumValue:TestResourceStatus.Failed", - "kind": "property", - "name": "Failed", - "declaration": "Failed = \u0022Failed\u0022", - "summary": "The resource failed." - } - ] - }, - { - "id": "interface:CSharpAppResource", - "kind": "interface", + "id": "augmentation:CSharpAppResource", + "kind": "augmentation", "name": "CSharpAppResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.CSharpAppResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface CSharpAppResource extends ResourceBuilderBase", "extends": [ "ResourceBuilderBase" @@ -659,11 +492,11 @@ ] }, { - "id": "interface:ContainerRegistryResource", - "kind": "interface", + "id": "augmentation:ContainerRegistryResource", + "kind": "augmentation", "name": "ContainerRegistryResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerRegistryResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ContainerRegistryResource extends ResourceBuilderBase", "extends": [ "ResourceBuilderBase" @@ -1109,11 +942,11 @@ ] }, { - "id": "interface:ContainerResource", - "kind": "interface", + "id": "augmentation:ContainerResource", + "kind": "augmentation", "name": "ContainerResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ContainerResource extends ResourceBuilderBase", "summary": "A resource that represents a specified container.", "extends": [ @@ -1592,11 +1425,11 @@ ] }, { - "id": "interface:DistributedApplicationBuilder", - "kind": "interface", + "id": "augmentation:DistributedApplicationBuilder", + "kind": "augmentation", "name": "DistributedApplicationBuilder", "typeId": "Aspire.Hosting/Aspire.Hosting.IDistributedApplicationBuilder", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface DistributedApplicationBuilder", "summary": "A builder for creating instances of {@ats-ref type:DistributedApplication}.", "members": [ @@ -1641,11 +1474,11 @@ ] }, { - "id": "interface:DotnetToolResource", - "kind": "interface", + "id": "augmentation:DotnetToolResource", + "kind": "augmentation", "name": "DotnetToolResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.DotnetToolResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface DotnetToolResource extends ResourceBuilderBase", "extends": [ "ResourceBuilderBase" @@ -2123,11 +1956,11 @@ ] }, { - "id": "interface:ExecutableResource", - "kind": "interface", + "id": "augmentation:ExecutableResource", + "kind": "augmentation", "name": "ExecutableResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ExecutableResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ExecutableResource extends ResourceBuilderBase", "summary": "A resource that represents a specified executable process.", "remarks": "You can run any executable command using its full path.\nAs a security feature, Aspire doesn\u0027t run executable unless the command is located in a path listed in the PATH environment variable.\nTo run an executable file that\u0027s in the current directory, specify the full path or use the relative path \u0060./\u0060 to represent the current directory.", @@ -2607,11 +2440,11 @@ ] }, { - "id": "interface:ExternalServiceResource", - "kind": "interface", + "id": "augmentation:ExternalServiceResource", + "kind": "augmentation", "name": "ExternalServiceResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ExternalServiceResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ExternalServiceResource extends ResourceBuilderBase", "extends": [ "ResourceBuilderBase" @@ -3057,11 +2890,11 @@ ] }, { - "id": "interface:ParameterResource", - "kind": "interface", + "id": "augmentation:ParameterResource", + "kind": "augmentation", "name": "ParameterResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ParameterResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ParameterResource extends ResourceBuilderBase", "summary": "Represents a parameter resource.", "extends": [ @@ -3508,11 +3341,11 @@ ] }, { - "id": "interface:ProjectResource", - "kind": "interface", + "id": "augmentation:ProjectResource", + "kind": "augmentation", "name": "ProjectResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ProjectResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ProjectResource extends ResourceBuilderBase", "summary": "A resource that represents a specified .NET project.", "extends": [ @@ -3991,11 +3824,11 @@ ] }, { - "id": "interface:Resource", - "kind": "interface", + "id": "augmentation:Resource", + "kind": "augmentation", "name": "Resource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface Resource extends ResourceBuilderBase", "summary": "Represents a resource that can be hosted by an application.", "extends": [ @@ -4442,11 +4275,11 @@ ] }, { - "id": "interface:ResourceWithConnectionString", - "kind": "interface", + "id": "augmentation:ResourceWithConnectionString", + "kind": "augmentation", "name": "ResourceWithConnectionString", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithConnectionString", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ResourceWithConnectionString extends ResourceBuilderBase", "summary": "Represents a resource that has a connection string associated with it.", "extends": [ @@ -4488,11 +4321,11 @@ ] }, { - "id": "interface:ResourceWithEnvironment", - "kind": "interface", + "id": "augmentation:ResourceWithEnvironment", + "kind": "augmentation", "name": "ResourceWithEnvironment", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithEnvironment", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "owningAssembly": "Aspire.Hosting", "declaration": "export interface ResourceWithEnvironment extends ResourceBuilderBase", "summary": "Represents a resource that is associated with an environment.", "extends": [ @@ -4533,6 +4366,173 @@ } ] }, + { + "id": "dto:TestConfigDto", + "kind": "dto", + "name": "TestConfigDto", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestConfigDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestConfigDto", + "summary": "Test DTO to verify [AspireDto] generates TypeScript interfaces.", + "members": [ + { + "id": "property:TestConfigDto.name", + "kind": "property", + "name": "name", + "declaration": "name?: string", + "summary": "The name of the test config." + }, + { + "id": "property:TestConfigDto.port", + "kind": "property", + "name": "port", + "declaration": "port?: number", + "summary": "The port used by the test config." + }, + { + "id": "property:TestConfigDto.enabled", + "kind": "property", + "name": "enabled", + "declaration": "enabled?: boolean", + "summary": "A value indicating whether the test config is enabled." + }, + { + "id": "property:TestConfigDto.optionalField", + "kind": "property", + "name": "optionalField", + "declaration": "optionalField?: string | null", + "summary": "An optional test config field." + } + ] + }, + { + "id": "dto:TestDeeplyNestedDto", + "kind": "dto", + "name": "TestDeeplyNestedDto", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestDeeplyNestedDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestDeeplyNestedDto", + "summary": "Test DTO with deeply nested generic types.", + "members": [ + { + "id": "property:TestDeeplyNestedDto.nestedData", + "kind": "property", + "name": "nestedData", + "declaration": "nestedData?: Record\u003Cstring, TestConfigDto[]\u003E", + "summary": "Deeply nested generic: Dictionary containing List of DTOs." + }, + { + "id": "property:TestDeeplyNestedDto.metadataArray", + "kind": "property", + "name": "metadataArray", + "declaration": "metadataArray?: Record\u003Cstring, string\u003E[]", + "summary": "Array of dictionaries." + } + ] + }, + { + "id": "dto:TestNestedDto", + "kind": "dto", + "name": "TestNestedDto", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestNestedDto", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface TestNestedDto", + "summary": "Test DTO with complex nested types.", + "members": [ + { + "id": "property:TestNestedDto.id", + "kind": "property", + "name": "id", + "declaration": "id?: string" + }, + { + "id": "property:TestNestedDto.config", + "kind": "property", + "name": "config", + "declaration": "config?: TestConfigDto" + }, + { + "id": "property:TestNestedDto.tags", + "kind": "property", + "name": "tags", + "declaration": "tags?: string[]" + }, + { + "id": "property:TestNestedDto.counts", + "kind": "property", + "name": "counts", + "declaration": "counts?: Record\u003Cstring, number\u003E" + } + ] + }, + { + "id": "enum:TestPersistenceMode", + "kind": "enum", + "name": "TestPersistenceMode", + "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestPersistenceMode", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export enum TestPersistenceMode", + "summary": "Test persistence mode enum.", + "members": [ + { + "id": "enumValue:TestPersistenceMode.None", + "kind": "property", + "name": "None", + "declaration": "None = \u0022None\u0022" + }, + { + "id": "enumValue:TestPersistenceMode.Volume", + "kind": "property", + "name": "Volume", + "declaration": "Volume = \u0022Volume\u0022" + }, + { + "id": "enumValue:TestPersistenceMode.Bind", + "kind": "property", + "name": "Bind", + "declaration": "Bind = \u0022Bind\u0022" + } + ] + }, + { + "id": "enum:TestResourceStatus", + "kind": "enum", + "name": "TestResourceStatus", + "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestResourceStatus", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export enum TestResourceStatus", + "summary": "Test enum for type generation verification.", + "members": [ + { + "id": "enumValue:TestResourceStatus.Pending", + "kind": "property", + "name": "Pending", + "declaration": "Pending = \u0022Pending\u0022", + "summary": "The resource is pending." + }, + { + "id": "enumValue:TestResourceStatus.Running", + "kind": "property", + "name": "Running", + "declaration": "Running = \u0022Running\u0022", + "summary": "The resource is running." + }, + { + "id": "enumValue:TestResourceStatus.Stopped", + "kind": "property", + "name": "Stopped", + "declaration": "Stopped = \u0022Stopped\u0022", + "summary": "The resource is stopped." + }, + { + "id": "enumValue:TestResourceStatus.Failed", + "kind": "property", + "name": "Failed", + "declaration": "Failed = \u0022Failed\u0022", + "summary": "The resource failed." + } + ] + }, { "id": "interface:TestCallbackContext", "kind": "interface", diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index 77410e468c6..d2a627e4a33 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -60,12 +60,28 @@ public void ExportApi_ScopesDocumentedItemsToRequestedPackage() .Select(declaration => declaration.GetProperty("owningAssembly").GetString()) .ToHashSet(StringComparer.Ordinal); - var itemOwners = export.GetProperty("modules").EnumerateArray() + var items = export.GetProperty("modules").EnumerateArray() .SelectMany(module => module.GetProperty("items").EnumerateArray()) + .ToList(); + + // Augmentations are the exception: they carry the members this package contributes to a type + // another package owns, so they report that owner and use a distinct stable ID rather than + // publishing a second page for someone else's type. + var ownedItemOwners = items + .Where(item => item.GetProperty("kind").GetString() != "augmentation") .Select(item => item.GetProperty("owningAssembly").GetString()) .ToHashSet(StringComparer.Ordinal); - Assert.All(itemOwners, owner => Assert.Equal("Aspire.Hosting", owner)); + Assert.All(ownedItemOwners, owner => Assert.Equal("Aspire.Hosting", owner)); + + Assert.All( + items.Where(item => item.GetProperty("kind").GetString() == "augmentation"), + item => + { + Assert.StartsWith("augmentation:", item.GetProperty("id").GetString(), StringComparison.Ordinal); + Assert.NotEqual("Aspire.Hosting", item.GetProperty("owningAssembly").GetString()); + }); + Assert.Contains("Aspire.Hosting", declarationOwners); } From 337e0758d890e37cc3cb7645f76d759f0c4017bb Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 18:44:25 -0400 Subject: [PATCH 07/73] Pin out-of-repo scanner packages with VersionOverride The generated capability scanner writes a Directory.Packages.props that turns central package management on, which rejects an inline Version attribute with NU1008. Any integration outside the repo failed to build, so sdk export could not be pointed at a third-party package. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../DotNetBasedAppHostServerProject.cs | 6 +- ...BasedAppHostServerPackageReferenceTests.cs | 59 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index d6ab64c689c..2413850ecde 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -217,10 +217,14 @@ private XDocument CreateProjectFile(IEnumerable integratio if (otherPackages.Count > 0) { + // This project always gets a generated Directory.Packages.props that turns central package + // management on, so an inline Version attribute is rejected with NU1008. VersionOverride is + // the CPM-sanctioned way to pin a single reference, and it lets us scan an integration that + // the repo's Directory.Packages.props has no PackageVersion entry for. doc.Root!.Add(new XElement("ItemGroup", otherPackages.Select(p => new XElement("PackageReference", new XAttribute("Include", p.Name), - new XAttribute("Version", p.Version))))); + new XAttribute("VersionOverride", p.Version))))); } // Add imports for in-repo AppHost building diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs new file mode 100644 index 00000000000..17356f56b09 --- /dev/null +++ b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Xml.Linq; +using Aspire.Cli.Configuration; +using Aspire.Cli.Projects; +using Aspire.Cli.Tests.Mcp; +using Aspire.Cli.Tests.TestServices; +using Aspire.Cli.Tests.Utils; +using Microsoft.Extensions.Logging.Abstractions; + +namespace Aspire.Cli.Tests.Projects; + +/// +/// The generated capability scanner writes its own Directory.Packages.props that turns central +/// package management on so transitive dependencies pick up the repo's pinned versions. Central package +/// management rejects an inline Version attribute on a PackageReference with NU1008, which +/// made the scanner fail to build for any integration that lives outside the repo — the exact case +/// aspire sdk export hits when it is pointed at a third-party package such as a Community Toolkit +/// integration. +/// +public class DotNetBasedAppHostServerPackageReferenceTests(ITestOutputHelper outputHelper) +{ + [Fact] + public async Task CreateProjectFiles_PinsOutOfRepoIntegrationsWithVersionOverride() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + var projectModelPath = Path.Combine(appPath, ".aspire_server"); + + var project = new DotNetBasedAppHostServerProject( + appPath, + socketPath: "test.sock", + repoRoot: appPath, + new TestDotNetCliRunner(), + MockPackagingServiceFactory.Create(), + new TestProcessExecutionFactory(), + new TestEnvironment(), + NullLogger.Instance, + projectModelPath); + + // There is no src/CommunityToolkit.Aspire.Hosting.ActiveMQ under the fake repo root, so this + // integration takes the package path rather than the project-reference path. + await project.CreateProjectFilesAsync( + [IntegrationReference.FromPackage("CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0")]); + + var packagesProps = XDocument.Load(Path.Combine(projectModelPath, "Directory.Packages.props")); + Assert.Equal( + "true", + packagesProps.Descendants("ManagePackageVersionsCentrally").Single().Value); + + var reference = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")) + .Descendants("PackageReference") + .Single(element => element.Attribute("Include")?.Value == "CommunityToolkit.Aspire.Hosting.ActiveMQ"); + + Assert.Equal("13.4.0", reference.Attribute("VersionOverride")?.Value); + Assert.Null(reference.Attribute("Version")); + } +} From 0f8419840eaf2007220c9024ff7da78fd649e914 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 18:44:25 -0400 Subject: [PATCH 08/73] Dispose the scanner session when startup fails Ownership only transfers to PreparedSdkSession once one is returned. A throw from StartAsync or GetRpcClientAsync left the spawned scanner running and holding the temp directory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../Commands/Sdk/SdkCommandPreparation.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs index 50f6a759452..d1523903908 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs @@ -162,15 +162,25 @@ public static bool TryParseIntegrationArgument( var serverSession = serverSessionFactory.Create(appHostServerProject, environmentVariables: null, debug: false, gracefulShutdownSignaler: null, shutdownService: null, isolateConsole: false, cancellationToken); - // Short-lived RPC session: StartAsync() spawns the server. We never observe the - // exit-code task (WaitForExitAsync) because disposal flows the exit code through the - // activity scope and the only failure mode we care about surfaces via the RPC call. - await serverSession.StartAsync(); + try + { + // Short-lived RPC session: StartAsync() spawns the server. We never observe the + // exit-code task (WaitForExitAsync) because disposal flows the exit code through the + // activity scope and the only failure mode we care about surfaces via the RPC call. + await serverSession.StartAsync(); - var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); + var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); - disposeTempDirectory = false; - return new PreparedSdkSession(serverSession, rpcClient, tempDir, logger); + disposeTempDirectory = false; + return new PreparedSdkSession(serverSession, rpcClient, tempDir, logger); + } + catch + { + // Ownership only transfers to PreparedSdkSession once we return one. Until then a + // failed start leaves the scanner process alive and holding the temp directory. + await serverSession.DisposeAsync(); + throw; + } } finally { From e9f54d70c121bf009311bc45e14e8b1a8169dda7 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 18:44:34 -0400 Subject: [PATCH 09/73] Normalize declaration content line endings Fragments built from raw string literals carry whatever line endings the source was checked out with, so a Windows build disagreed with a Linux build about identical declarations. Consumers deduplicate a manifest by comparing content for the same ID, so the text has to be stable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../TypeScriptApiModel.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs index 12395692f19..deb3f21aeba 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs @@ -173,11 +173,23 @@ internal sealed record TypeScriptApiModule /// internal sealed record TypeScriptApiDeclaration { + private readonly string _content = string.Empty; + /// Gets the stable, generator-owned identifier used for ordering and deduplication. public required string Id { get; init; } /// Gets the TypeScript declaration text. - public required string Content { get; init; } + /// + /// Line endings are normalized to \n. Some fragments come from raw string literals, which + /// carry whatever line endings the source file was checked out with, and consumers deduplicate + /// fragments by comparing content across packages — so a CLI built on Windows would otherwise + /// disagree with one built on Linux about the very same declaration. + /// + public required string Content + { + get => _content; + init => _content = value.ReplaceLineEndings("\n"); + } /// Gets the assembly that owns the declared symbol. public required string OwningAssemblyName { get; init; } From e3e506e659baa43382dc960163d45c9bfb152871 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 18:44:34 -0400 Subject: [PATCH 10/73] Make augmentation IDs unique and project client-only DTO properties Every integration that extends DistributedApplicationBuilder produced the same augmentation item ID, which recreated the cross-package collision the augmentation kind exists to avoid, so the contributing package is now part of the ID. CreateBuilderOptions also gained its client-only throwOnPendingRejections property from the module emitter alone, so the export described a smaller interface than the one we ship. That list moved to the projector and both paths read it from there. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../AtsTypeScriptCodeGenerator.cs | 9 +- .../TypeScriptApiProjector.cs | 49 +++++++++-- .../AtsTypeScriptCodeGeneratorTests.cs | 86 ++++++++++++++++++- ...CodeGeneratorTests.ApiExport.verified.json | 24 +++--- 4 files changed, 144 insertions(+), 24 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index b661fc5508b..20b44ca4131 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -701,11 +701,12 @@ private void GenerateDtoInterfaces(IReadOnlyList dtoTypes) WriteLine($" {propName}?: {tsType};"); } - // Add client-only properties that don't exist in the C# DTO - if (dto.Name == "CreateBuilderOptions") + // Client-only properties have no C# counterpart. The list lives on the projector so the + // exported API surface describes the same interface this emits. + foreach (var clientOnly in TypeScriptApiProjector.GetClientOnlyDtoProperties(interfaceName)) { - WriteLine(" /** When false, pre-flush rejected promises are not re-thrown by build(). Default: true. */"); - WriteLine(" throwOnPendingRejections?: boolean;"); + WriteLine($" /** {clientOnly.Summary} */"); + WriteLine($" {clientOnly.Name}?: {clientOnly.Type};"); } WriteLine("}"); diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 224012d8233..21c58e70a43 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -617,7 +617,7 @@ internal TypeScriptApiModel BuildApiModel( }); } - return (BuildInterfaceItem(builderModel, interfaceName, extends, typeOwner, documentation, members, TypeScriptApiItemKind.Interface), declarations); + return (BuildInterfaceItem(builderModel, $"interface:{interfaceName}", interfaceName, extends, typeOwner, documentation, members, TypeScriptApiItemKind.Interface), declarations); } // The referenced type gets an opaque stub keyed by its real owner so every package that @@ -667,12 +667,15 @@ internal TypeScriptApiModel BuildApiModel( // The item carries the real owner and a distinct ID: the owning package already publishes a // page for this type, and reusing "interface:{name}" here would collide with it across a - // manifest and claim the type belongs to whichever package happened to extend it. - return (BuildInterfaceItem(builderModel, interfaceName, extends, typeOwner, documentation, contributedMembers, TypeScriptApiItemKind.Augmentation), declarations); + // manifest and claim the type belongs to whichever package happened to extend it. The + // contributing package is part of the ID because every integration that extends + // DistributedApplicationBuilder produces an augmentation for the same interface name. + return (BuildInterfaceItem(builderModel, $"augmentation:{package.Name}:{interfaceName}", interfaceName, extends, typeOwner, documentation, contributedMembers, TypeScriptApiItemKind.Augmentation), declarations); } private static TypeScriptApiItem BuildInterfaceItem( BuilderModel builderModel, + string id, string interfaceName, string[] extends, string owningAssemblyName, @@ -681,9 +684,7 @@ private static TypeScriptApiItem BuildInterfaceItem( TypeScriptApiItemKind kind) => new() { - Id = kind == TypeScriptApiItemKind.Augmentation - ? $"augmentation:{interfaceName}" - : $"interface:{interfaceName}", + Id = id, TypeId = builderModel.TypeId, Kind = kind, Name = interfaceName, @@ -884,6 +885,26 @@ private static (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) Pr }); } + /// + /// Properties the TypeScript client adds to a DTO that has no C# counterpart. The emitter used to + /// own this list, so the exported interface described fewer properties than the module we actually + /// ship. Both paths read it from here now. + /// + private static readonly IReadOnlyDictionary> s_clientOnlyDtoProperties = + new Dictionary>(StringComparer.Ordinal) + { + ["CreateBuilderOptions"] = + [ + new ClientOnlyDtoProperty( + "throwOnPendingRejections", + "boolean", + "When false, pre-flush rejected promises are not re-thrown by build(). Default: true.") + ] + }; + + internal static IReadOnlyList GetClientOnlyDtoProperties(string interfaceName) + => s_clientOnlyDtoProperties.TryGetValue(interfaceName, out var properties) ? properties : []; + private (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) ProjectDto(AtsDtoTypeInfo dtoType) { var interfaceName = GetDtoInterfaceName(dtoType.TypeId); @@ -908,6 +929,16 @@ private static (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) Pr }) .ToList(); + members.AddRange(GetClientOnlyDtoProperties(interfaceName).Select(property => new TypeScriptApiMember + { + Id = $"property:{interfaceName}.{property.Name}", + Kind = TypeScriptApiItemKind.Property, + Name = property.Name, + Declaration = $"{property.Name}?: {property.Type}", + Summary = property.Summary, + OwningAssemblyName = owningAssemblyName + })); + var item = new TypeScriptApiItem { Id = $"dto:{interfaceName}", @@ -2359,3 +2390,9 @@ internal string GenerateCallbackTypeSignature(IReadOnlyList Promise<{returnType}>"; } } + +/// +/// A DTO property that exists only on the TypeScript side, with the type and summary both the module +/// emitter and the API export render. +/// +internal sealed record ClientOnlyDtoProperty(string Name, string Type, string Summary); diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index b81223cb18b..240f3bfd1f1 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2077,6 +2077,82 @@ public void ApiExportDeclarationsAppearInGeneratedPublicInterfaces() Assert.True(checkedDeclarations > 0, "The canonical export produced no method declarations to compare."); } + /// + /// DTO interfaces carry properties that have no C# counterpart, such as the client-only + /// throwOnPendingRejections on CreateBuilderOptions. Those used to be appended by the + /// module emitter alone, so the exported interface described fewer properties than the module we + /// ship and aspire.dev documented a DTO nobody could actually pass. + /// + [Fact] + public void ApiExportDtoPropertiesMatchTheGeneratedDtoInterfaces() + { + var atsContext = CreateOwnershipFilteredContext(); + + var projector = new TypeScriptApiProjector(atsContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(atsContext)["aspire.mts"]; + + var checkedDtos = 0; + foreach (var item in model.Modules.SelectMany(module => module.Items).Where(item => item.Kind == TypeScriptApiItemKind.Dto)) + { + var body = ExtractExportedInterfaceBody(generatedSource, item.Name); + Assert.NotNull(body); + + var generatedProperties = body! + .Split('\n', StringSplitOptions.RemoveEmptyEntries) + .Select(line => line.Trim()) + .Where(line => line.EndsWith(';') && !line.StartsWith("//", StringComparison.Ordinal) && !line.StartsWith("*", StringComparison.Ordinal) && !line.StartsWith("/*", StringComparison.Ordinal)) + .Select(line => line[..^1]) + .ToList(); + + Assert.Equal(generatedProperties, item.Members.Select(member => member.Declaration).ToList()); + checkedDtos++; + } + + Assert.True(checkedDtos > 0, "The canonical export produced no DTO items to compare."); + } + + /// + /// Returns the body of export interface {name} { ... } from generated module source, or + /// when the generated source declares no such interface. + /// + private static string? ExtractExportedInterfaceBody(string generatedSource, string interfaceName) + { + var header = $"export interface {interfaceName} {{"; + var start = generatedSource.IndexOf(header, StringComparison.Ordinal); + if (start < 0) + { + return null; + } + + var bodyStart = start + header.Length; + var end = generatedSource.IndexOf("\n}", bodyStart, StringComparison.Ordinal); + return end < 0 ? null : generatedSource[bodyStart..end]; + } + + /// + /// Consumers deduplicate declaration fragments by comparing content for the same ID across packages, + /// so the text has to be byte-identical no matter which OS produced the export. Some fragments come + /// from raw string literals, which pick up CRLF when the repository is checked out on Windows. + /// + [Fact] + public void ApiExportDeclarationContentUsesPlatformIndependentLineEndings() + { + var atsContext = CreateOwnershipFilteredContext(); + + var projector = new TypeScriptApiProjector(atsContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + Assert.All(model.Declarations, declaration => + Assert.DoesNotContain('\r', declaration.Content)); + } + [Fact] public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() { @@ -2101,15 +2177,21 @@ public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() // A package that extends another package's type must not publish a second page for it. The // owning package's export uses "interface:{name}" for that type, so an augmentation reusing - // that ID would collide across a manifest and claim ownership it does not have. + // that ID would collide across a manifest and claim ownership it does not have. The + // contributing package is part of the ID as well, because every integration that extends + // DistributedApplicationBuilder augments the same interface name. Assert.All( documentedItems.Where(item => item.Kind == TypeScriptApiItemKind.Augmentation), item => { - Assert.StartsWith("augmentation:", item.Id, StringComparison.Ordinal); + Assert.StartsWith($"augmentation:{TestPackageName}:", item.Id, StringComparison.Ordinal); Assert.NotEqual(TestPackageName, item.OwningAssemblyName); }); + // Item IDs are what aspire.dev deduplicates a manifest on, so a repeat would silently drop a page. + var itemIds = documentedItems.Select(item => item.Id).ToList(); + Assert.Equal(itemIds.Count, itemIds.Distinct(StringComparer.Ordinal).Count()); + // Members are owned per capability, so no documented member may come from another assembly. Assert.All( documentedItems.SelectMany(item => item.Members), diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index 5e830233b87..bd3bd243058 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -10,7 +10,7 @@ "name": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", "items": [ { - "id": "augmentation:CSharpAppResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:CSharpAppResource", "kind": "augmentation", "name": "CSharpAppResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.CSharpAppResource", @@ -492,7 +492,7 @@ ] }, { - "id": "augmentation:ContainerRegistryResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ContainerRegistryResource", "kind": "augmentation", "name": "ContainerRegistryResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerRegistryResource", @@ -942,7 +942,7 @@ ] }, { - "id": "augmentation:ContainerResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ContainerResource", "kind": "augmentation", "name": "ContainerResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerResource", @@ -1425,7 +1425,7 @@ ] }, { - "id": "augmentation:DistributedApplicationBuilder", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:DistributedApplicationBuilder", "kind": "augmentation", "name": "DistributedApplicationBuilder", "typeId": "Aspire.Hosting/Aspire.Hosting.IDistributedApplicationBuilder", @@ -1474,7 +1474,7 @@ ] }, { - "id": "augmentation:DotnetToolResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:DotnetToolResource", "kind": "augmentation", "name": "DotnetToolResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.DotnetToolResource", @@ -1956,7 +1956,7 @@ ] }, { - "id": "augmentation:ExecutableResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ExecutableResource", "kind": "augmentation", "name": "ExecutableResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ExecutableResource", @@ -2440,7 +2440,7 @@ ] }, { - "id": "augmentation:ExternalServiceResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ExternalServiceResource", "kind": "augmentation", "name": "ExternalServiceResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ExternalServiceResource", @@ -2890,7 +2890,7 @@ ] }, { - "id": "augmentation:ParameterResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ParameterResource", "kind": "augmentation", "name": "ParameterResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ParameterResource", @@ -3341,7 +3341,7 @@ ] }, { - "id": "augmentation:ProjectResource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ProjectResource", "kind": "augmentation", "name": "ProjectResource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ProjectResource", @@ -3824,7 +3824,7 @@ ] }, { - "id": "augmentation:Resource", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:Resource", "kind": "augmentation", "name": "Resource", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource", @@ -4275,7 +4275,7 @@ ] }, { - "id": "augmentation:ResourceWithConnectionString", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ResourceWithConnectionString", "kind": "augmentation", "name": "ResourceWithConnectionString", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithConnectionString", @@ -4321,7 +4321,7 @@ ] }, { - "id": "augmentation:ResourceWithEnvironment", + "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ResourceWithEnvironment", "kind": "augmentation", "name": "ResourceWithEnvironment", "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithEnvironment", From f08d9e1bef2d637bb8e34aa1dc5e069f723eb16a Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 19:19:22 -0400 Subject: [PATCH 11/73] Reject core version skew in sdk export The scanner never honored a requested core version. Both PrepareAsync implementations accept sdkVersion and ignore it, so `sdk export --package Aspire.Hosting@13.0.0` returned byte-identical JSON to a 13.5.0-dev export, relabelled 13.0.0. That is the stale-signature problem this command exists to fix. Honoring the request is not possible: the prebuilt server bundles core and the RPC host compiled together, so loading a foreign core would break the RPC contract. Reject the skew instead, with a message pointing at the CLI that can produce the requested export. Integration packages are unaffected: they become real PackageReferences and already resolve to the requested version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- .../Commands/Sdk/SdkExportCommand.cs | 28 +++++++++++++- .../Commands/Sdk/SdkExportCommandTests.cs | 38 +++++++++++++++++-- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 62df25e8648..070eb263c73 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -113,7 +113,23 @@ protected override async Task ExecuteAsync(ParseResult parseResul // The core package is always restored by the scanner AppHost, so adding it again would // produce a duplicate package reference. - if (!string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase)) + { + // The scanner loads the core assemblies this CLI was built against, so a different + // requested version would be exported as this CLI's surface under someone else's + // version number. That is the same stale-signature problem this command exists to + // fix, so refuse instead of labelling the export with a version it does not describe. + var requested = StripBuildMetadata(packageVersion); + if (!string.Equals(requested, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) + { + return CommandResult.Failure( + CliExitCodes.InvalidCommand, + $"This CLI can only export {CorePackageName}@{ExecutionContext.IdentitySdkVersion}, but {packageVersion} was requested. " + + $"The scanner loads the core assemblies this CLI ships with, so exporting a different version would describe the wrong API surface. " + + $"Run the export with the {requested} CLI instead."); + } + } + else { integrations.Add(reference); } @@ -167,6 +183,16 @@ protected override async Task ExecuteAsync(ParseResult parseResul } } + /// + /// Drops SemVer build metadata so 13.5.0+abc123 and 13.5.0 compare equal, matching + /// how normalizes this CLI's own version. + /// + private static string StripBuildMetadata(string version) + { + var plusIndex = version.IndexOf('+', StringComparison.Ordinal); + return plusIndex < 0 ? version : version[..plusIndex]; + } + private async Task ExportApiAsync( string language, string packageName, diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 1a3b540fdc7..d19aef2eaa3 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -80,7 +80,7 @@ public async Task SdkExportSendsProgressToStderrOnly() using var provider = CreateProvider(interactionService, out var workspace, out _); using var _2 = workspace; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0"); + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); Assert.Equal(CliExitCodes.Success, exitCode); Assert.DoesNotContain( @@ -96,7 +96,7 @@ public async Task SdkExportPassesPackageSourceThroughToPrepare() var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0 --source /tmp/aspire-hive"); + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0 --source /tmp/aspire-hive"); Assert.Equal(CliExitCodes.Success, exitCode); Assert.Equal("/tmp/aspire-hive", appHostServerProject.PackageSourceOverride); @@ -115,7 +115,7 @@ public async Task SdkExportAddsTheCodeGenerationPackageForTheRequestedLanguage() var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0"); + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); Assert.Equal(CliExitCodes.Success, exitCode); Assert.Contains( @@ -141,6 +141,38 @@ public async Task SdkExportWithMalformedPackageReturnsInvalidCommand(string pack Assert.Empty(interactionService.DisplayedRawText); } + [Fact] + public async Task SdkExportWithMismatchedCoreVersionReturnsInvalidCommand() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out _); + using var _2 = workspace; + + // The scanner loads the core assemblies this CLI ships with, so honouring a different core + // version would export this CLI's surface under someone else's version number — the same + // stale-signature problem this command exists to fix. + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@1.0.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Empty(interactionService.DisplayedRawText); + } + + [Fact] + public async Task SdkExportAcceptsCoreVersionThatDiffersOnlyByBuildMetadata() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out _); + using var _2 = workspace; + + var executionContext = provider.GetRequiredService(); + + var exitCode = await InvokeAsync( + provider, + $"sdk export --language typescript --package Aspire.Hosting@{executionContext.IdentitySdkVersion}+build.5"); + + Assert.Equal(0, exitCode); + } + [Theory] [InlineData("13.5.*")] [InlineData("[13.5.0,14.0.0)")] From bb03ab930ecf6f56da68a9c7d5a46947abb624eb Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 19:39:33 -0400 Subject: [PATCH 12/73] Route sdk export diagnostics to stderr The command always emits JSON, so it has no --format option for BaseCommand's json redirect to key off. Preparation diagnostics and the --output success message therefore went to stdout and corrupted the document when a caller piped it. DisplaySuccess takes no per-call override, so it could not opt out. Route the interaction service to stderr at command entry. The JSON write already overrides back to stdout explicitly, and an explicit override wins over the service setting. SdkExportSendsProgressToStderrOnly asserted on the per-call override, which is null for these calls, so it passed vacuously. It now resolves the effective destination and covers the --output path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs | 6 ++++++ .../Commands/Sdk/SdkExportCommandTests.cs | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 070eb263c73..59616265a09 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -73,6 +73,12 @@ public SdkExportCommand( protected override async Task ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken) { + // This command always emits machine-readable JSON, so it has no --format option for + // BaseCommand's json redirect to key off. Without this, preparation diagnostics and the + // --output success message land on stdout and corrupt the document a caller is piping. + // The JSON write overrides back to stdout explicitly, and an explicit override wins. + InteractionService.Console = ConsoleOutput.Error; + var language = parseResult.GetValue(s_languageOption)!; var package = parseResult.GetValue(s_packageOption); var packageSource = parseResult.GetValue(s_sourceOption); diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index d19aef2eaa3..39e53ad2d2a 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -80,12 +80,20 @@ public async Task SdkExportSendsProgressToStderrOnly() using var provider = CreateProvider(interactionService, out var workspace, out _); using var _2 = workspace; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0 --output " + Path.Combine(workspace.WorkspaceRoot.FullName, "api.json")); Assert.Equal(CliExitCodes.Success, exitCode); + + // A null per-call override means the message follows the service's Console, so asserting on + // the override alone passes vacuously. Resolve the effective destination instead. + Assert.Equal(ConsoleOutput.Error, interactionService.Console); Assert.DoesNotContain( interactionService.DisplayedMessages, - message => message.ConsoleOverride == ConsoleOutput.Standard); + message => (message.ConsoleOverride ?? interactionService.Console) == ConsoleOutput.Standard); + + // DisplaySuccess cannot be overridden per call, so the --output confirmation would land on + // stdout and corrupt a piped document if the service were not routed to stderr. + Assert.NotEmpty(interactionService.DisplayedSuccess); } [Fact] From b35c38ba841ad90111d87e1bcc8e851263143871 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 5 Aug 2026 20:10:48 -0400 Subject: [PATCH 13/73] Restore the generated scanner project in the CPM test The VersionOverride regression test only inspected the generated XML, so it could not catch a change in how NuGet treats VersionOverride under central package management. Restore the generated project for real against an offline folder feed, with a central package list that deliberately has no entry for the out-of-repo integration. Reverting VersionOverride to an inline Version attribute now fails the test with NU1008. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 819baaf4-91c3-44ce-8004-3dbc9110f810 --- ...BasedAppHostServerPackageReferenceTests.cs | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs index 17356f56b09..ce174c8538d 100644 --- a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; +using System.IO.Compression; using System.Xml.Linq; using Aspire.Cli.Configuration; using Aspire.Cli.Projects; @@ -56,4 +58,120 @@ await project.CreateProjectFilesAsync( Assert.Equal("13.4.0", reference.Attribute("VersionOverride")?.Value); Assert.Null(reference.Attribute("Version")); } + + /// + /// Asserting on the generated XML alone cannot catch a change in how NuGet treats + /// VersionOverride under central package management. This restores the generated project + /// for real against an offline folder feed, with a central package list that deliberately has no + /// entry for the out-of-repo integration, so a regression surfaces as NU1008 or NU1010. + /// + [Fact] + public async Task CreateProjectFiles_ProducesAProjectThatRestores() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + var projectModelPath = Path.Combine(appPath, ".aspire_server"); + var feedPath = Path.Combine(appPath, "feed"); + Directory.CreateDirectory(feedPath); + + const string IntegrationPackage = "CommunityToolkit.Aspire.Hosting.ActiveMQ"; + + // The template always references these two without a version, so they have to resolve + // through the central list the way they do in the real repo. + CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); + CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); + CreateStubPackage(feedPath, IntegrationPackage, "13.4.0"); + + // Mirrors the real repo: a central list that pins first-party dependencies but knows nothing + // about a Community Toolkit integration. + await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), """ + + + + + + + """); + + var project = new DotNetBasedAppHostServerProject( + appPath, + socketPath: "test.sock", + repoRoot: appPath, + new TestDotNetCliRunner(), + MockPackagingServiceFactory.Create(), + new TestProcessExecutionFactory(), + new TestEnvironment(), + NullLogger.Instance, + projectModelPath); + + await project.CreateProjectFilesAsync( + [IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")]); + + var (exitCode, output) = await RestoreAsync( + Path.Combine(projectModelPath, "AppHostServer.csproj"), + feedPath); + + outputHelper.WriteLine(output); + + // NU1008 is the inline Version attribute this fix replaced; NU1010 is the failure mode that + // would appear if VersionOverride stopped satisfying the central list requirement. + Assert.DoesNotContain("NU1008", output, StringComparison.Ordinal); + Assert.DoesNotContain("NU1010", output, StringComparison.Ordinal); + Assert.Equal(0, exitCode); + } + + private static void CreateStubPackage(string feedPath, string id, string version) + { + var stagingPath = Path.Combine(feedPath, $".staging-{id}"); + Directory.CreateDirectory(Path.Combine(stagingPath, "lib", "net10.0")); + + File.WriteAllText(Path.Combine(stagingPath, $"{id}.nuspec"), $""" + + + + {id} + {version} + Stub package for restore tests. + Aspire + + + """); + + File.WriteAllText(Path.Combine(stagingPath, "[Content_Types].xml"), """ + + + + + + + """); + + File.WriteAllBytes(Path.Combine(stagingPath, "lib", "net10.0", $"{id}.dll"), []); + + ZipFile.CreateFromDirectory(stagingPath, Path.Combine(feedPath, $"{id}.{version}.nupkg")); + Directory.Delete(stagingPath, recursive: true); + } + + private static async Task<(int ExitCode, string Output)> RestoreAsync(string projectPath, string feedPath) + { + var startInfo = new ProcessStartInfo("dotnet") + { + RedirectStandardOutput = true, + RedirectStandardError = true, + WorkingDirectory = Path.GetDirectoryName(projectPath)! + }; + + startInfo.ArgumentList.Add("restore"); + startInfo.ArgumentList.Add(projectPath); + // Replaces every configured source so the restore cannot reach the network. + startInfo.ArgumentList.Add("--source"); + startInfo.ArgumentList.Add(feedPath); + + using var process = Process.Start(startInfo)!; + var stdoutTask = process.StandardOutput.ReadToEndAsync(); + var stderrTask = process.StandardError.ReadToEndAsync(); + await process.WaitForExitAsync(); + + return (process.ExitCode, await stdoutTask + await stderrTask); + } } From 4397483fedcffadb200df1bcd3b9d1bc341f3dc4 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 00:39:00 -0400 Subject: [PATCH 14/73] Fix TypeScript API export parameters Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ffeff87e-f284-434d-87d3-843e21a7aebb --- .../AtsTypeScriptCodeGenerator.cs | 184 +++----- .../TypeScriptApiModel.cs | 14 +- .../TypeScriptApiProjector.cs | 64 ++- .../AtsTypeScriptCodeGeneratorTests.cs | 132 ++++++ ...CodeGeneratorTests.ApiExport.verified.json | 401 +++++------------- 5 files changed, 342 insertions(+), 453 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index 20b44ca4131..734aabb620f 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -960,31 +960,25 @@ private void GenerateBuilderInterface(BuilderModel builder) c.CapabilityKind != AtsCapabilityKind.PropertyGetter && c.CapabilityKind != AtsCapabilityKind.PropertySetter)) { - var targetParamName = capability.TargetParameterName ?? "builder"; - var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); - var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); - var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var publicParamsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); + var signature = _projector.ResolveMethodSignature(builder, capability); var hasNonBuilderReturn = !capability.ReturnsBuilder && capability.ReturnType != null; - WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? "options" : null); + WriteCapabilityDocComment(" ", capability, signature.RequiredParameters, signature.OptionsParameter?.Name); if (hasNonBuilderReturn) { if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var promiseInterfaceName, out _)) { - WriteLine($" {capability.MethodName}({publicParamsString}): {promiseInterfaceName};"); + WriteLine($" {capability.MethodName}({signature.ParameterList}): {promiseInterfaceName};"); } else { var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); - WriteLine($" {capability.MethodName}({publicParamsString}): Promise<{returnType}>;"); + WriteLine($" {capability.MethodName}({signature.ParameterList}): Promise<{returnType}>;"); } } else { - WriteLine($" {capability.MethodName}({publicParamsString}): {_projector.GetBuilderPromiseInterfaceForMethod(builder, capability)};"); + WriteLine($" {capability.MethodName}({signature.ParameterList}): {_projector.GetBuilderPromiseInterfaceForMethod(builder, capability)};"); } } @@ -1020,31 +1014,25 @@ private void GenerateBuilderPromiseInterface(BuilderModel builder) foreach (var capability in capabilities) { - var targetParamName = capability.TargetParameterName ?? "builder"; - var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); - var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); - var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); + var signature = _projector.ResolveMethodSignature(builder, capability); var hasNonBuilderReturn = !capability.ReturnsBuilder && capability.ReturnType != null; - WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? "options" : null); + WriteCapabilityDocComment(" ", capability, signature.RequiredParameters, signature.OptionsParameter?.Name); if (hasNonBuilderReturn) { if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out _)) { - WriteLine($" {capability.MethodName}({paramsString}): {returnPromiseInterfaceName};"); + WriteLine($" {capability.MethodName}({signature.ParameterList}): {returnPromiseInterfaceName};"); } else { var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); - WriteLine($" {capability.MethodName}({paramsString}): Promise<{returnType}>;"); + WriteLine($" {capability.MethodName}({signature.ParameterList}): Promise<{returnType}>;"); } } else { - WriteLine($" {capability.MethodName}({paramsString}): {_projector.GetBuilderPromiseInterfaceForMethod(builder, capability)};"); + WriteLine($" {capability.MethodName}({signature.ParameterList}): {_projector.GetBuilderPromiseInterfaceForMethod(builder, capability)};"); } } @@ -1052,33 +1040,24 @@ private void GenerateBuilderPromiseInterface(BuilderModel builder) WriteLine(); } - private void GenerateTypeClassInterfaceMethod(string className, AtsCapabilityInfo capability) + private void GenerateTypeClassInterfaceMethod(BuilderModel model, string className, AtsCapabilityInfo capability) { - var methodName = !string.IsNullOrEmpty(capability.OwningTypeName) && capability.MethodName.Contains('.') - ? capability.MethodName[(capability.MethodName.LastIndexOf('.') + 1)..] - : TypeScriptApiProjector.GetTypeScriptMethodName(capability.MethodName); - var targetParamName = capability.TargetParameterName ?? "context"; - var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); - var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); - var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, trailingCancellationToken: TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); + var signature = _projector.ResolveMethodSignature(model, capability); var isVoid = capability.ReturnType == null || capability.ReturnType.TypeId == AtsConstants.Void; - WriteCapabilityDocComment(" ", capability, requiredParams, hasOptionals ? "options" : null); + WriteCapabilityDocComment(" ", capability, signature.RequiredParameters, signature.OptionsParameter?.Name); if (capability.ReturnType != null && _projector.TypesWithPromiseWrappers.Contains(capability.ReturnType.TypeId)) { - WriteLine($" {methodName}({paramsString}): {_projector.GetPublicPromiseInterfaceName(capability.ReturnType.TypeId)};"); + WriteLine($" {signature.MethodName}({signature.ParameterList}): {_projector.GetPublicPromiseInterfaceName(capability.ReturnType.TypeId)};"); } else if (isVoid) { - WriteLine($" {methodName}({paramsString}): {TypeScriptApiProjector.GetPromiseInterfaceName(className)};"); + WriteLine($" {signature.MethodName}({signature.ParameterList}): {TypeScriptApiProjector.GetPromiseInterfaceName(className)};"); } else { var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); - WriteLine($" {methodName}({paramsString}): Promise<{returnType}>;"); + WriteLine($" {signature.MethodName}({signature.ParameterList}): Promise<{returnType}>;"); } } @@ -1113,7 +1092,7 @@ private void GenerateTypeClassInterface(BuilderModel model) foreach (var method in standardMethods) { - GenerateTypeClassInterfaceMethod(className, method); + GenerateTypeClassInterfaceMethod(model, className, method); } WriteLine("}"); @@ -1132,7 +1111,7 @@ private void GenerateTypeClassInterface(BuilderModel model) } foreach (var method in standardMethods) { - GenerateTypeClassInterfaceMethod(className, method); + GenerateTypeClassInterfaceMethod(model, className, method); } WriteLine("}"); WriteLine(); @@ -1766,47 +1745,19 @@ private void GenerateThenableClass(BuilderModel builder) // Filter out property getters and setters - they are not methods foreach (var capability in capabilities) { - var methodName = capability.MethodName; - var targetParamName = capability.TargetParameterName ?? "builder"; - var userParams = capability.Parameters.Where(p => p.Name != targetParamName).ToList(); - - // Separate required and optional parameters - var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); - var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsTypeName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var trailingCancellationToken = TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams); - - // Build parameter list using options pattern - var publicParamDefs = new List(); - foreach (var param in requiredParams) - { - var tsType = _projector.MapParameterToTypeScript(param); - publicParamDefs.Add($"{param.Name}: {tsType}"); - } - if (hasOptionals) - { - publicParamDefs.Add($"options?: {optionsTypeName}"); - } - if (trailingCancellationToken is not null) - { - publicParamDefs.Add($"{trailingCancellationToken.Name}?: {_projector.MapParameterToTypeScript(trailingCancellationToken)}"); - } - var paramsString = string.Join(", ", publicParamDefs); + var signature = _projector.ResolveMethodSignature(builder, capability); // Forward args to underlying object's method (which handles options extraction) - var forwardArgs = new List(); - foreach (var param in requiredParams) - { - forwardArgs.Add(param.Name); - } - if (hasOptionals) + var forwardArgs = signature.RequiredParameters + .Select(parameter => parameter.Name) + .ToList(); + if (signature.OptionsParameter is { } optionsParameter) { - forwardArgs.Add("options"); + forwardArgs.Add(optionsParameter.Name); } - if (trailingCancellationToken is not null) + if (signature.TrailingCancellationToken is { } cancellationToken) { - forwardArgs.Add(trailingCancellationToken.Name); + forwardArgs.Add(cancellationToken.Name); } var argsString = string.Join(", ", forwardArgs); @@ -1817,10 +1768,10 @@ private void GenerateThenableClass(BuilderModel builder) { if (_projector.TryGetPromiseWrapperType(capability.ReturnType, out var returnPromiseInterfaceName, out var returnPromiseImplementationClassName)) { - Write($" {methodName}("); - Write(paramsString); + Write($" {signature.MethodName}("); + Write(signature.ParameterList); WriteLine($"): {returnPromiseInterfaceName} {{"); - Write($" return new {returnPromiseImplementationClassName}(this._promise.then(obj => obj.{methodName}("); + Write($" return new {returnPromiseImplementationClassName}(this._promise.then(obj => obj.{signature.MethodName}("); Write(argsString); WriteLine(")), this._client);"); WriteLine(" }"); @@ -1830,10 +1781,10 @@ private void GenerateThenableClass(BuilderModel builder) // For non-builder returns, call the public method directly var returnType = _projector.MapTypeRefToTypeScript(capability.ReturnType); - Write($" {methodName}("); - Write(paramsString); + Write($" {signature.MethodName}("); + Write(signature.ParameterList); WriteLine($"): Promise<{returnType}> {{"); - Write($" return this._promise.then(obj => obj.{methodName}("); + Write($" return this._promise.then(obj => obj.{signature.MethodName}("); Write(argsString); WriteLine("));"); WriteLine(" }"); @@ -1854,12 +1805,12 @@ private void GenerateThenableClass(BuilderModel builder) methodPromiseImplementationClass = TypeScriptApiProjector.GetImplementationPromiseClassName(returnClass); } - Write($" {methodName}("); - Write(paramsString); + Write($" {signature.MethodName}("); + Write(signature.ParameterList); Write($"): {methodPromiseClass} {{"); WriteLine(); // Forward to the public method on the underlying object, wrapping result in promise class - Write($" return new {methodPromiseImplementationClass}(this._promise.then(obj => obj.{methodName}("); + Write($" return new {methodPromiseImplementationClass}(this._promise.then(obj => obj.{signature.MethodName}("); Write(argsString); WriteLine($")), this._client);"); WriteLine(" }"); @@ -3308,50 +3259,19 @@ private void GenerateTypeClassThenableWrapper(BuilderModel model, List p.Name != targetParamName).ToList(); - - // Separate required and optional parameters - var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(userParams); - var hasOptionals = optionalParams.Count > 0; - var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); - var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var trailingCancellationToken = TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams); - - // Build parameter list using options pattern - var publicParamDefs = new List(); - foreach (var param in requiredParams) - { - var tsType = _projector.MapParameterToTypeScript(param); - publicParamDefs.Add($"{param.Name}: {tsType}"); - } - if (hasOptionals) - { - publicParamDefs.Add($"options?: {optionsInterfaceName}"); - } - if (trailingCancellationToken is not null) - { - publicParamDefs.Add($"{trailingCancellationToken.Name}?: {_projector.MapParameterToTypeScript(trailingCancellationToken)}"); - } - var paramsString = string.Join(", ", publicParamDefs); + var signature = _projector.ResolveMethodSignature(model, capability); // Forward args to underlying object's public method - var forwardArgs = new List(); - foreach (var param in requiredParams) - { - forwardArgs.Add(param.Name); - } - if (hasOptionals) + var forwardArgs = signature.RequiredParameters + .Select(parameter => parameter.Name) + .ToList(); + if (signature.OptionsParameter is { } optionsParameter) { - forwardArgs.Add("options"); + forwardArgs.Add(optionsParameter.Name); } - if (trailingCancellationToken is not null) + if (signature.TrailingCancellationToken is { } cancellationToken) { - forwardArgs.Add(trailingCancellationToken.Name); + forwardArgs.Add(cancellationToken.Name); } var argsString = string.Join(", ", forwardArgs); @@ -3366,10 +3286,10 @@ private void GenerateTypeClassThenableWrapper(BuilderModel model, List obj.{methodName}("); + Write($" return new {returnPromiseImplementationClass}(this._promise.then(obj => obj.{signature.MethodName}("); Write(argsString); WriteLine($")), this._client);"); WriteLine(" }"); @@ -3377,10 +3297,10 @@ private void GenerateTypeClassThenableWrapper(BuilderModel model, List obj.{methodName}("); + Write($" return new {promiseImplementationClass}(this._promise.then(obj => obj.{signature.MethodName}("); Write(argsString); WriteLine($")), this._client);"); WriteLine(" }"); @@ -3388,10 +3308,10 @@ private void GenerateTypeClassThenableWrapper(BuilderModel model, List {{"); - Write($" return this._promise.then(obj => obj.{methodName}("); + Write($" return this._promise.then(obj => obj.{signature.MethodName}("); Write(argsString); WriteLine("));"); WriteLine(" }"); diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs index deb3f21aeba..c3b88a4aa54 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs @@ -234,17 +234,17 @@ internal sealed record TypeScriptApiMethodSignature /// Gets the final TypeScript return type text. public required string ReturnType { get; init; } + /// Gets the parameters exactly as they appear in the public TypeScript signature. + public required IReadOnlyList Parameters { get; init; } + /// Gets the required parameters, in declaration order. public required IReadOnlyList RequiredParameters { get; init; } - /// Gets the optional parameters, in declaration order. - public required IReadOnlyList OptionalParameters { get; init; } - - /// Gets a value indicating whether the method exposes an options bag. - public required bool HasOptions { get; init; } + /// Gets the resolved options bag parameter, when the method exposes one. + public TypeScriptApiParameter? OptionsParameter { get; init; } - /// Gets the options type name used for the options bag parameter. - public required string OptionsTypeName { get; init; } + /// Gets the cancellation token emitted separately after a direct options DTO. + public TypeScriptApiParameter? TrailingCancellationToken { get; init; } /// Gets the full declaration string, for example addRedis(name: string): RedisResourceBuilderPromise. public string Declaration => $"{MethodName}({ParameterList}): {ReturnType}"; diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 21c58e70a43..1c45c2a6583 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -269,11 +269,36 @@ internal TypeScriptApiMethodSignature ResolveMethodSignature(BuilderModel? build var optionsTypeName = hasDirectOptionsParameter ? MapParameterToTypeScript(directOptionsParam!) : ResolveOptionsInterfaceName(capability); - var parameterList = BuildPublicParameterList( - requiredParams, - hasOptionals, - optionsTypeName, - trailingCancellationToken: GetTrailingCancellationTokenParameter(optionalParams)); + var optionsParameterName = GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var trailingCancellationToken = GetTrailingCancellationTokenParameter(optionalParams); + var publicParameters = requiredParams + .Select(ProjectPublicParameter) + .ToList(); + TypeScriptApiParameter? optionsParameter = null; + + if (hasOptionals) + { + optionsParameter = new TypeScriptApiParameter + { + Name = optionsParameterName, + DeclaredType = optionsTypeName, + IsOptional = true, + Summary = directOptionsParam?.Documentation?.Summary + }; + publicParameters.Add(optionsParameter); + } + + TypeScriptApiParameter? publicCancellationToken = null; + if (trailingCancellationToken is not null) + { + publicCancellationToken = ProjectPublicParameter(trailingCancellationToken); + publicParameters.Add(publicCancellationToken); + } + + var parameterList = string.Join( + ", ", + publicParameters.Select(parameter => + $"{parameter.Name}{(parameter.IsOptional ? "?" : string.Empty)}: {parameter.DeclaredType}")); return new TypeScriptApiMethodSignature { @@ -282,11 +307,20 @@ internal TypeScriptApiMethodSignature ResolveMethodSignature(BuilderModel? build ReturnType = isTypeClass ? ResolveTypeClassReturnType(builder!, capability) : ResolveBuilderReturnType(builder, capability), + Parameters = publicParameters, RequiredParameters = requiredParams, - OptionalParameters = optionalParams, - HasOptions = hasOptionals, - OptionsTypeName = optionsTypeName + OptionsParameter = optionsParameter, + TrailingCancellationToken = publicCancellationToken }; + + TypeScriptApiParameter ProjectPublicParameter(AtsParameterInfo parameter) + => new() + { + Name = parameter.Name, + DeclaredType = MapParameterToTypeScript(parameter), + IsOptional = parameter.IsOptional || parameter.IsNullable, + Summary = parameter.Documentation?.Summary + }; } /// @@ -731,18 +765,6 @@ private TypeScriptApiMember ProjectMethod( AtsCapabilityInfo capability) { var signature = ResolveMethodSignature(builderModel, capability); - var targetParamName = capability.TargetParameterName ?? "builder"; - - var parameters = capability.Parameters - .Where(p => builderModel is null || p.Name != targetParamName) - .Select(p => new TypeScriptApiParameter - { - Name = p.Name, - DeclaredType = MapParameterToTypeScript(p), - IsOptional = p.IsOptional || p.IsNullable, - Summary = p.Documentation?.Summary - }) - .ToList(); return new TypeScriptApiMember { @@ -755,7 +777,7 @@ private TypeScriptApiMember ProjectMethod( DeprecationMessage = capability.IsObsolete ? capability.ObsoleteMessage ?? string.Empty : null, CapabilityId = capability.CapabilityId, OwningAssemblyName = GetCapabilityOwningAssemblyName(capability), - Parameters = parameters, + Parameters = signature.Parameters, ReturnType = signature.ReturnType }; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 240f3bfd1f1..a81af76aee8 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1924,6 +1924,138 @@ await Verify(declarations, extension: "txt") .UseFileName("AtsTypeScriptCodeGeneratorTests.ApiDeclarations"); } + [Fact] + public void ApiExportMethodParametersMatchResolvedPublicSignatures() + { + var atsContext = CreateOwnershipFilteredContext(); + var template = atsContext.Capabilities.Single(c => + c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync"); + var stringParameter = atsContext.Capabilities + .Single(c => c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging") + .Parameters.Single(p => p.Name == "logLevel"); + var boolParameter = atsContext.Capabilities + .Single(c => c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString") + .Parameters.Single(p => p.Name == "enabled"); + var dtoParameter = atsContext.Capabilities + .Single(c => c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig") + .Parameters.Single(p => p.Name == "config"); + var cancellationTokenParameter = template.Parameters.Single(p => p.Name == "cancellationToken"); + + AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] parameters) + => new() + { + CapabilityId = $"{TestPackageName}/{methodName}", + MethodName = methodName, + Parameters = parameters, + ReturnType = template.ReturnType, + TargetTypeId = template.TargetTypeId, + TargetType = template.TargetType, + TargetParameterName = template.TargetParameterName, + ExpandedTargetTypes = template.ExpandedTargetTypes, + ReturnsBuilder = template.ReturnsBuilder, + CapabilityKind = template.CapabilityKind + }; + + var contextWithEdgeCases = WithAdditionalCapabilities( + atsContext, + CreateCapability( + "withOptionsCollision", + new AtsParameterInfo + { + Name = "options", + Type = stringParameter.Type, + Documentation = new AtsDocumentationInfo { Summary = "Required options value." } + }, + new AtsParameterInfo + { + Name = "optionsBag", + Type = stringParameter.Type, + Documentation = new AtsDocumentationInfo { Summary = "Required options bag value." } + }, + new AtsParameterInfo + { + Name = "enabled", + Type = boolParameter.Type, + IsOptional = true, + Documentation = new AtsDocumentationInfo { Summary = "Whether the behavior is enabled." } + }), + CreateCapability( + "withDirectOptionsAndCancellation", + new AtsParameterInfo + { + Name = "options", + Type = dtoParameter.Type, + IsOptional = true, + Documentation = new AtsDocumentationInfo { Summary = "Direct options." } + }, + new AtsParameterInfo + { + Name = "cancellationToken", + Type = cancellationTokenParameter.Type, + IsOptional = true, + Documentation = new AtsDocumentationInfo { Summary = "Cancellation token." } + })); + + var projector = new TypeScriptApiProjector(contextWithEdgeCases); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + var testRedisResource = Assert.Single( + model.Modules.SelectMany(module => module.Items), + item => item.Name == nameof(TestRedisResource)); + + var withOptionalString = Assert.Single( + testRedisResource.Members, + member => member.Name == "withOptionalString"); + Assert.Collection( + withOptionalString.Parameters, + parameter => AssertParameter(parameter, "options", "WithOptionalStringOptions", isOptional: true)); + + var withOptionsCollision = Assert.Single( + testRedisResource.Members, + member => member.Name == "withOptionsCollision"); + Assert.Equal( + "withOptionsCollision(options: string, optionsBag: string, _optionsBag?: WithOptionsCollisionOptions): Promise", + withOptionsCollision.Declaration); + Assert.Collection( + withOptionsCollision.Parameters, + parameter => AssertParameter(parameter, "options", "string", isOptional: false, "Required options value."), + parameter => AssertParameter(parameter, "optionsBag", "string", isOptional: false, "Required options bag value."), + parameter => AssertParameter(parameter, "_optionsBag", "WithOptionsCollisionOptions", isOptional: true)); + + var withDirectOptionsAndCancellation = Assert.Single( + testRedisResource.Members, + member => member.Name == "withDirectOptionsAndCancellation"); + Assert.Equal( + "withDirectOptionsAndCancellation(options?: TestConfigDto, cancellationToken?: AbortSignal | CancellationToken): Promise", + withDirectOptionsAndCancellation.Declaration); + Assert.Collection( + withDirectOptionsAndCancellation.Parameters, + parameter => AssertParameter(parameter, "options", "TestConfigDto", isOptional: true, "Direct options."), + parameter => AssertParameter(parameter, "cancellationToken", "AbortSignal | CancellationToken", isOptional: true, "Cancellation token.")); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(contextWithEdgeCases)["aspire.mts"]; + var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); + var testRedisResourceMembers = generatedInterfaceMembers[nameof(TestRedisResource)]; + + Assert.Contains(withOptionsCollision.Declaration, testRedisResourceMembers); + Assert.Contains(withDirectOptionsAndCancellation.Declaration, testRedisResourceMembers); + + static void AssertParameter( + TypeScriptApiParameter parameter, + string name, + string declaredType, + bool isOptional, + string? summary = null) + { + Assert.Equal(name, parameter.Name); + Assert.Equal(declaredType, parameter.DeclaredType); + Assert.Equal(isOptional, parameter.IsOptional); + Assert.Equal(summary, parameter.Summary); + } + } + /// /// The export contract promises that concatenating a manifest's declaration fragments type-checks /// without site-authored shims, so every symbol a fragment names must be declared by some fragment. diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index bd3bd243058..cb8fb7fe5d5 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -30,13 +30,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -131,8 +126,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -380,13 +375,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -411,13 +401,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -512,13 +497,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -597,8 +577,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -830,13 +810,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -861,13 +836,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -963,13 +933,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -1064,8 +1029,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -1313,13 +1278,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -1344,13 +1304,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -1449,8 +1404,8 @@ "summary": "The ATS resource name." }, { - "name": "port", - "type": "number", + "name": "options", + "type": "AddTestRedisOptions", "optional": true } ] @@ -1494,13 +1449,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -1595,8 +1545,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -1844,13 +1794,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -1875,13 +1820,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -1978,13 +1918,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -2079,8 +2014,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -2328,13 +2263,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -2359,13 +2289,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -2460,13 +2385,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -2545,8 +2465,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -2778,13 +2698,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -2809,13 +2724,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -2911,13 +2821,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -2996,8 +2901,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -3229,13 +3134,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -3260,13 +3160,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -3362,13 +3257,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -3463,8 +3353,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -3712,13 +3602,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -3743,13 +3628,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -3845,13 +3725,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -3930,8 +3805,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -4163,13 +4038,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -4194,13 +4064,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -4614,13 +4479,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -4715,8 +4575,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -4964,13 +4824,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -4995,13 +4850,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -5158,8 +5008,8 @@ "optional": false }, { - "name": "databaseName", - "type": "string", + "name": "options", + "type": "AddTestChildDatabaseOptions", "optional": true } ] @@ -5174,8 +5024,8 @@ "summary": "Configures the Redis resource with persistence", "parameters": [ { - "name": "mode", - "type": "TestPersistenceMode", + "name": "options", + "type": "WithPersistenceOptions", "optional": true } ] @@ -5190,13 +5040,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -5325,8 +5170,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -5510,8 +5355,8 @@ "summary": "Gets the status of the resource asynchronously", "parameters": [ { - "name": "cancellationToken", - "type": "AbortSignal | CancellationToken", + "name": "options", + "type": "GetStatusAsyncOptions", "optional": true } ] @@ -5547,8 +5392,8 @@ "optional": false }, { - "name": "cancellationToken", - "type": "AbortSignal | CancellationToken", + "name": "options", + "type": "WaitForReadyAsyncOptions", "optional": true } ] @@ -5579,13 +5424,8 @@ "summary": "Adds a data volume with persistence", "parameters": [ { - "name": "name", - "type": "string", - "optional": true - }, - { - "name": "isReadOnly", - "type": "boolean", + "name": "options", + "type": "WithDataVolumeOptions", "optional": true } ] @@ -5689,13 +5529,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -5720,13 +5555,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -5880,13 +5710,8 @@ "summary": "Adds an optional string parameter", "parameters": [ { - "name": "value", - "type": "string", - "optional": true - }, - { - "name": "enabled", - "type": "boolean", + "name": "options", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -5981,8 +5806,8 @@ "summary": "Configures with optional callback", "parameters": [ { - "name": "callback", - "type": "(arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E", + "name": "options", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -6246,13 +6071,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -6277,13 +6097,8 @@ "optional": false }, { - "name": "enableConsole", - "type": "boolean", - "optional": true - }, - { - "name": "maxFiles", - "type": "number", + "name": "options", + "type": "WithMergeLoggingPathOptions", "optional": true } ] From 492474163c867fcc8be1dea79f9abd65be9528f1 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 04:16:11 -0400 Subject: [PATCH 15/73] Preserve TypeScript API export ownership Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ffeff87e-f284-434d-87d3-843e21a7aebb --- .../AtsTypeScriptCodeGenerator.cs | 8 +- .../TypeScriptApiModel.cs | 9 +- .../TypeScriptApiProjector.cs | 68 +++- .../AtsCapabilityScanner.cs | 25 +- .../AtsContextFilter.cs | 230 ++++++++++- .../CodeGeneration/CodeGenerationService.cs | 11 +- .../ApiReferenceExportOptions.cs | 11 +- src/Aspire.TypeSystem/AtsContext.cs | 11 + .../AtsTypeScriptCodeGeneratorTests.cs | 381 +++++++++++++++++- ...eneratorTests.ApiDeclarations.verified.txt | 78 ++-- ...CodeGeneratorTests.ApiExport.verified.json | 146 ++++--- .../AtsContextFilterTests.cs | 65 +++ 12 files changed, 927 insertions(+), 116 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index 734aabb620f..7dac5819ffa 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -1211,7 +1211,7 @@ private void GenerateBuilderMethod(BuilderModel builder, AtsCapabilityInfo capab var hasOptionals = optionalParams.Count > 0; var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); var optionsTypeName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var publicOptionsParamName = TypeScriptApiProjector.GetImplementationOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list for public method var publicParamsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsTypeName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); @@ -2775,7 +2775,7 @@ private void GenerateContextMethod(AtsCapabilityInfo method) var hasOptionals = optionalParams.Count > 0; var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(method); - var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var publicOptionsParamName = TypeScriptApiProjector.GetImplementationOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list using options pattern var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); @@ -2890,7 +2890,7 @@ private void GenerateWrapperMethod(AtsCapabilityInfo capability) var hasOptionals = optionalParams.Count > 0; var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var publicOptionsParamName = TypeScriptApiProjector.GetImplementationOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list using options pattern var paramsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); @@ -3008,7 +3008,7 @@ private void GenerateTypeClassMethod(BuilderModel model, AtsCapabilityInfo capab var hasOptionals = optionalParams.Count > 0; var hasDirectOptionsParameter = TypeScriptApiProjector.TryGetDirectOptionsParameter(optionalParams, out var directOptionsParam); var optionsInterfaceName = hasDirectOptionsParameter ? _projector.MapParameterToTypeScript(directOptionsParam!) : _projector.ResolveOptionsInterfaceName(capability); - var publicOptionsParamName = TypeScriptApiProjector.GetPublicOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); + var publicOptionsParamName = TypeScriptApiProjector.GetImplementationOptionsParameterName(userParams, hasOptionals, hasDirectOptionsParameter); // Build parameter list for public method var publicParamsString = _projector.BuildPublicParameterList(requiredParams, hasOptionals, optionsInterfaceName, publicOptionsParamName, TypeScriptApiProjector.GetTrailingCancellationTokenParameter(optionalParams)); diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs index c3b88a4aa54..8e4b60224f4 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs @@ -228,15 +228,18 @@ internal sealed record TypeScriptApiMethodSignature /// Gets the generated method name. public required string MethodName { get; init; } - /// Gets the rendered public parameter list, without the surrounding parentheses. - public required string ParameterList { get; init; } - /// Gets the final TypeScript return type text. public required string ReturnType { get; init; } /// Gets the parameters exactly as they appear in the public TypeScript signature. public required IReadOnlyList Parameters { get; init; } + /// Gets the rendered public parameter list, without the surrounding parentheses. + public string ParameterList => string.Join( + ", ", + Parameters.Select(parameter => + $"{parameter.Name}{(parameter.IsOptional ? "?" : string.Empty)}: {parameter.DeclaredType}")); + /// Gets the required parameters, in declaration order. public required IReadOnlyList RequiredParameters { get; init; } diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 1c45c2a6583..8c8a63ff6cc 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -295,15 +295,9 @@ internal TypeScriptApiMethodSignature ResolveMethodSignature(BuilderModel? build publicParameters.Add(publicCancellationToken); } - var parameterList = string.Join( - ", ", - publicParameters.Select(parameter => - $"{parameter.Name}{(parameter.IsOptional ? "?" : string.Empty)}: {parameter.DeclaredType}")); - return new TypeScriptApiMethodSignature { MethodName = isTypeClass ? ResolveTypeClassMethodName(capability) : capability.MethodName, - ParameterList = parameterList, ReturnType = isTypeClass ? ResolveTypeClassReturnType(builder!, capability) : ResolveBuilderReturnType(builder, capability), @@ -597,9 +591,12 @@ internal TypeScriptApiModel BuildApiModel( ? builderModel.BuilderClassName : DeriveClassName(builderModel.TypeId)); var members = new List(); + var exportedCapabilities = builderModel.Capabilities + .Where(capability => ownedAssemblyNames.Contains(GetCapabilityOwningAssemblyName(capability))) + .ToList(); - var getters = builderModel.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); - var setters = builderModel.Capabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); + var getters = exportedCapabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); + var setters = exportedCapabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); foreach (var property in GroupPropertiesByName(getters, setters)) { @@ -610,10 +607,10 @@ internal TypeScriptApiModel BuildApiModel( // non-property capability. Mirroring that split keeps the export aligned with the interfaces // the generator actually writes. var methods = isResourceBuilder - ? builderModel.Capabilities.Where(c => + ? exportedCapabilities.Where(c => c.CapabilityKind != AtsCapabilityKind.PropertyGetter && c.CapabilityKind != AtsCapabilityKind.PropertySetter) - : builderModel.Capabilities.Where(c => + : exportedCapabilities.Where(c => c.CapabilityKind is AtsCapabilityKind.InstanceMethod or AtsCapabilityKind.Method); foreach (var capability in methods) @@ -673,11 +670,7 @@ internal TypeScriptApiModel BuildApiModel( }); } - var contributedMembers = members - .Where(member => member.OwningAssemblyName is { } memberOwner && ownedAssemblyNames.Contains(memberOwner)) - .ToList(); - - if (contributedMembers.Count == 0) + if (members.Count == 0) { return (null, declarations); } @@ -685,7 +678,7 @@ internal TypeScriptApiModel BuildApiModel( declarations.Add(new TypeScriptApiDeclaration { Id = $"{package.Name}:augment:{interfaceName}", - Content = BuildInterfaceBody(interfaceName, [], contributedMembers, includeToJson: false), + Content = BuildInterfaceBody(interfaceName, [], members, includeToJson: false), OwningAssemblyName = package.Name }); @@ -694,7 +687,7 @@ internal TypeScriptApiModel BuildApiModel( declarations.Add(new TypeScriptApiDeclaration { Id = $"{package.Name}:augment:{promiseInterfaceName}", - Content = BuildInterfaceBody(promiseInterfaceName, [], contributedMembers, includeToJson: false), + Content = BuildInterfaceBody(promiseInterfaceName, [], members, includeToJson: false), OwningAssemblyName = package.Name }); } @@ -704,7 +697,7 @@ internal TypeScriptApiModel BuildApiModel( // manifest and claim the type belongs to whichever package happened to extend it. The // contributing package is part of the ID because every integration that extends // DistributedApplicationBuilder produces an augmentation for the same interface name. - return (BuildInterfaceItem(builderModel, $"augmentation:{package.Name}:{interfaceName}", interfaceName, extends, typeOwner, documentation, contributedMembers, TypeScriptApiItemKind.Augmentation), declarations); + return (BuildInterfaceItem(builderModel, $"augmentation:{package.Name}:{interfaceName}", interfaceName, extends, typeOwner, documentation, members, TypeScriptApiItemKind.Augmentation), declarations); } private static TypeScriptApiItem BuildInterfaceItem( @@ -1072,6 +1065,11 @@ private static string GetOwningAssemblyName(string atsId, string? clrAssemblyNam /// private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) { + if (_resolved.Context.CapabilityExportingAssemblyNames.TryGetValue(capability.CapabilityId, out var exportingAssemblyName)) + { + return exportingAssemblyName; + } + if (_resolved.Context.Methods.TryGetValue(capability.CapabilityId, out var method)) { return method.DeclaringType?.Assembly.GetName().Name ?? string.Empty; @@ -1831,6 +1829,40 @@ internal static string GetPublicOptionsParameterName( return "options"; } + var (requiredParams, optionalParams) = SeparateParameters(userParams); + var trailingCancellationToken = GetTrailingCancellationTokenParameter(optionalParams); + + bool IsPublicParameterName(string name) + => requiredParams.Any(p => string.Equals(p.Name, name, StringComparison.Ordinal)) + || string.Equals(trailingCancellationToken?.Name, name, StringComparison.Ordinal); + + if (!IsPublicParameterName("options")) + { + return "options"; + } + + var candidate = "optionsBag"; + while (IsPublicParameterName(candidate)) + { + candidate = $"_{candidate}"; + } + + return candidate; + } + + internal static string GetImplementationOptionsParameterName( + IReadOnlyList userParams, + bool hasOptionals, + bool hasDirectOptionsParameter) + { + if (!hasOptionals || hasDirectOptionsParameter) + { + return "options"; + } + + // Implementation methods destructure every optional field into a local with its source + // parameter name. Unlike the public interface, their options-bag parameter must therefore + // avoid optional names too (for example: const options = optionsBag?.options). if (!userParams.Any(p => string.Equals(p.Name, "options", StringComparison.Ordinal))) { return "options"; diff --git a/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs b/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs index 9e586055de3..c20302d6c47 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs @@ -56,6 +56,11 @@ public sealed class ScanResult /// public Dictionary Properties { get; init; } = new(); + /// + /// Runtime registry mapping capability IDs to the assemblies that exported them. + /// + internal Dictionary CapabilityExportingAssemblyNames { get; init; } = new(); + /// /// Converts the scan result to an AtsContext for code generation. /// @@ -68,7 +73,8 @@ public AtsContext ToAtsContext() DtoTypes = DtoTypes, EnumTypes = EnumTypes, ExportedValues = ExportedValues, - Diagnostics = Diagnostics + Diagnostics = Diagnostics, + CapabilityExportingAssemblyNames = CapabilityExportingAssemblyNames }; // Copy runtime registries @@ -80,7 +86,6 @@ public AtsContext ToAtsContext() { context.Properties[id] = property; } - return context; } } @@ -146,6 +151,7 @@ public static ScanResult ScanAssemblies( var allDiagnostics = new List(); var allMethods = new Dictionary(); var allProperties = new Dictionary(); + var allCapabilityExportingAssemblyNames = new Dictionary(); var seenCapabilities = new Dictionary(); // Track capability ID -> first capability for duplicate detection var seenTypeIds = new HashSet(); var seenDtoTypeIds = new HashSet(); @@ -212,6 +218,10 @@ public static ScanResult ScanAssemblies( { allProperties.TryAdd(id, property); } + foreach (var (id, assemblyName) in result.CapabilityExportingAssemblyNames) + { + allCapabilityExportingAssemblyNames.TryAdd(id, assemblyName); + } // Merge diagnostics allDiagnostics.AddRange(result.Diagnostics); @@ -243,7 +253,8 @@ public static ScanResult ScanAssemblies( ExportedValues = allExportedValues, Diagnostics = allDiagnostics, Methods = allMethods, - Properties = allProperties + Properties = allProperties, + CapabilityExportingAssemblyNames = allCapabilityExportingAssemblyNames }; } @@ -283,7 +294,8 @@ public static ScanResult ScanAssembly( ExportedValues = exportedValues, Diagnostics = result.Diagnostics, Methods = result.Methods, - Properties = result.Properties + Properties = result.Properties, + CapabilityExportingAssemblyNames = result.CapabilityExportingAssemblyNames }; } @@ -513,7 +525,10 @@ private static ScanResult ScanAssemblyWithoutExpansion( ExportedValues = exportedValues, Diagnostics = diagnostics, Methods = methods, - Properties = properties + Properties = properties, + CapabilityExportingAssemblyNames = capabilities + .GroupBy(static capability => capability.CapabilityId, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, _ => assemblyName, StringComparer.Ordinal) }; } diff --git a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs index 394c9a33c53..a5b98774208 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs @@ -33,6 +33,119 @@ public static AtsContext FilterByExportingAssembliesWithReferences( IReadOnlyCollection assemblyNames) => FilterByExportingAssemblies(context, assemblyNames, includeReferencedTypes: true); + /// + /// Filters an ATS context for API export while retaining enough capability metadata to resolve + /// the generated wrapper shape of referenced handle types. + /// + /// + /// A package can return a handle owned by another assembly. The generated SDK still exposes that + /// handle through its wrapper when the referenced type has chainable members, so the exporter + /// needs to see those member kinds even though it must not republish the members themselves. + /// Supporting capabilities retain their target, member kind, and referenced handle types. Their + /// callable shape is otherwise removed so foreign API and options interfaces cannot leak into the + /// package export while wrapper unions still match full source generation. + /// + /// The ATS context to filter. + /// The names of the assemblies whose API is being exported. + /// The filtered API export context. + internal static AtsContext FilterForApiExport( + AtsContext context, + IReadOnlyCollection assemblyNames) + { + ArgumentNullException.ThrowIfNull(context); + ArgumentNullException.ThrowIfNull(assemblyNames); + + var filteredContext = FilterByExportingAssemblies(context, assemblyNames, includeReferencedTypes: true); + var normalizedAssemblyNames = new HashSet( + assemblyNames.Where(static name => !string.IsNullOrWhiteSpace(name)), + StringComparer.OrdinalIgnoreCase); + + if (normalizedAssemblyNames.Count == 0) + { + return filteredContext; + } + + var capabilityTargetTypeIds = filteredContext.Capabilities + .SelectMany(GetCapabilityTargetTypeIds) + .ToHashSet(StringComparer.Ordinal); + var supportingHandleTypes = filteredContext.HandleTypes + .Where(type => + !capabilityTargetTypeIds.Contains(type.AtsTypeId) && + !IsOwnedBySelectedAssembly(type.ClrType?.Assembly, type.AtsTypeId, normalizedAssemblyNames)) + .ToDictionary(type => type.AtsTypeId, StringComparer.Ordinal); + if (supportingHandleTypes.Count == 0) + { + return filteredContext; + } + + var includedCapabilityIds = filteredContext.Capabilities + .Select(capability => capability.CapabilityId) + .ToHashSet(StringComparer.Ordinal); + var supportingCapabilities = context.Capabilities + .Where(capability => !includedCapabilityIds.Contains(capability.CapabilityId)) + .SelectMany(capability => CreateApiExportSupportCapabilities(capability, supportingHandleTypes)) + .ToList(); + + if (supportingCapabilities.Count == 0) + { + return filteredContext; + } + + var capabilities = filteredContext.Capabilities.Concat(supportingCapabilities).ToList(); + var apiExportContext = new AtsContext + { + Capabilities = capabilities, + HandleTypes = filteredContext.HandleTypes, + DtoTypes = filteredContext.DtoTypes, + EnumTypes = filteredContext.EnumTypes, + ExportedValues = filteredContext.ExportedValues, + Diagnostics = filteredContext.Diagnostics, + CapabilityExportingAssemblyNames = capabilities + .Where(capability => context.CapabilityExportingAssemblyNames.ContainsKey(capability.CapabilityId)) + .ToDictionary( + capability => capability.CapabilityId, + capability => context.CapabilityExportingAssemblyNames[capability.CapabilityId], + StringComparer.Ordinal) + }; + + foreach (var capability in capabilities) + { + // Instance capability IDs can be namespace-qualified rather than assembly-qualified. + // Keep the reflection registries so the exporter attributes each retained capability to + // the assembly that actually declares it instead of guessing from the ID prefix. + if (context.Methods.TryGetValue(capability.CapabilityId, out var method)) + { + apiExportContext.Methods[capability.CapabilityId] = method; + } + + if (context.Properties.TryGetValue(capability.CapabilityId, out var property)) + { + apiExportContext.Properties[capability.CapabilityId] = property; + } + + } + + return apiExportContext; + } + + private static IEnumerable GetCapabilityTargetTypeIds(AtsCapabilityInfo capability) + { + if (capability.TargetTypeId is { } targetTypeId) + { + yield return targetTypeId; + } + + if (capability.TargetType is { } targetType) + { + yield return targetType.TypeId; + } + + foreach (var expandedTargetType in capability.ExpandedTargetTypes) + { + yield return expandedTargetType.TypeId; + } + } + private static AtsContext FilterByExportingAssemblies( AtsContext context, IReadOnlyCollection assemblyNames, @@ -138,7 +251,13 @@ private static AtsContext FilterByExportingAssemblies( ExportedValues = filteredExportedValues, Diagnostics = context.Diagnostics .Where(diagnostic => IsDiagnosticOwnedBySelectedAssembly(context, diagnostic, normalizedAssemblyNames, knownAssemblyNames)) - .ToList() + .ToList(), + CapabilityExportingAssemblyNames = filteredCapabilities + .Where(capability => context.CapabilityExportingAssemblyNames.ContainsKey(capability.CapabilityId)) + .ToDictionary( + capability => capability.CapabilityId, + capability => context.CapabilityExportingAssemblyNames[capability.CapabilityId], + StringComparer.Ordinal) }; foreach (var capability in filteredCapabilities) @@ -152,11 +271,115 @@ private static AtsContext FilterByExportingAssemblies( { filteredContext.Properties[capability.CapabilityId] = property; } + } return filteredContext; } + private static IEnumerable CreateApiExportSupportCapabilities( + AtsCapabilityInfo capability, + IReadOnlyDictionary supportingHandleTypes) + { + if (!GetCapabilityTargetTypeIds(capability).Any(supportingHandleTypes.ContainsKey)) + { + yield break; + } + + var targetType = capability.TargetType; + if (targetType is null && + capability.TargetTypeId is { } targetTypeId && + supportingHandleTypes.TryGetValue(targetTypeId, out var handleType)) + { + targetType = new AtsTypeRef + { + TypeId = targetTypeId, + ClrType = handleType.ClrType, + Category = AtsTypeCategory.Handle, + IsInterface = handleType.IsInterface, + ImplementedInterfaces = handleType.ImplementedInterfaces + }; + } + + yield return new AtsCapabilityInfo + { + CapabilityId = capability.CapabilityId, + MethodName = capability.MethodName, + OwningTypeName = capability.OwningTypeName, + // The canonical exporter needs the same handle universe as full source generation. + // Preserve foreign handle references as required synthetic parameters so wrapper + // unions stay identical without importing the foreign member's options interface. + Parameters = CreateApiExportSupportParameters(capability), + ReturnType = new AtsTypeRef + { + TypeId = AtsConstants.Void, + Category = AtsTypeCategory.Primitive + }, + TargetTypeId = capability.TargetTypeId, + TargetType = targetType, + TargetParameterName = capability.TargetParameterName, + // Keep the complete expansion. Full source generation applies the member to every + // implementer, and those wrappers participate in interface-parameter unions even when + // only one implementer was directly referenced by the exporting package. + ExpandedTargetTypes = capability.ExpandedTargetTypes, + ReturnsBuilder = false, + CapabilityKind = capability.CapabilityKind + }; + } + + private static IReadOnlyList CreateApiExportSupportParameters(AtsCapabilityInfo capability) + { + var referencedHandleTypes = new Dictionary(StringComparer.Ordinal); + + CollectHandleTypes(capability.ReturnType); + foreach (var parameter in capability.Parameters) + { + CollectHandleTypes(parameter.Type); + if (parameter.CallbackParameters is { } callbackParameters) + { + foreach (var callbackParameter in callbackParameters) + { + CollectHandleTypes(callbackParameter.Type); + } + } + + CollectHandleTypes(parameter.CallbackReturnType); + } + + return referencedHandleTypes + .OrderBy(static pair => pair.Key, StringComparer.Ordinal) + .Select(static (pair, index) => new AtsParameterInfo + { + Name = $"__apiExportSupportType{index}", + Type = pair.Value + }) + .ToList(); + + void CollectHandleTypes(AtsTypeRef? typeRef) + { + if (typeRef is null) + { + return; + } + + if (typeRef.Category == AtsTypeCategory.Handle && !string.IsNullOrEmpty(typeRef.TypeId)) + { + referencedHandleTypes.TryAdd(typeRef.TypeId, typeRef); + } + + CollectHandleTypes(typeRef.ElementType); + CollectHandleTypes(typeRef.KeyType); + CollectHandleTypes(typeRef.ValueType); + if (typeRef.UnionTypes is { } unionTypes) + { + foreach (var unionType in unionTypes) + { + CollectHandleTypes(unionType); + } + } + } + } + private static void CollectReferencedType( AtsTypeRef? typeRef, IReadOnlyDictionary handleTypesById, @@ -251,6 +474,11 @@ private static bool IsCapabilityOwnedBySelectedAssembly( AtsCapabilityInfo capability, HashSet assemblyNames) { + if (context.CapabilityExportingAssemblyNames.TryGetValue(capability.CapabilityId, out var exportingAssemblyName)) + { + return assemblyNames.Contains(exportingAssemblyName); + } + if (context.Methods.TryGetValue(capability.CapabilityId, out var method)) { return IsSelectedAssembly(method.DeclaringType?.Assembly, assemblyNames); diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index e40322936aa..7bcea10da92 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -248,6 +248,9 @@ public Dictionary GenerateCode(string language, string? assembly var context = _atsContextFactory.GetContext(); if (!string.IsNullOrWhiteSpace(assemblyName)) { + // Scoped source generation must not use the API-export filter: its synthetic + // supporting capabilities are projection-only metadata and would otherwise become + // executable members in the generated SDK. context = AtsContextFilter.FilterByExportingAssembliesWithReferences(context, [assemblyName]); } @@ -305,10 +308,10 @@ public JsonElement ExportApi(string language, string packageName, string package $"Supported languages for API export: {BuildApiExportLanguageList()}."); } - // The reference closure is required for the exported declarations to be self-contained, - // but the exporter still needs the unexpanded set to know which symbols this package - // actually owns and should document. - var context = AtsContextFilter.FilterByExportingAssembliesWithReferences( + // Referenced handle capabilities determine wrapper and resource-union signatures. + // Keep only their projection support shape without publishing their API as part of this + // package. + var context = AtsContextFilter.FilterForApiExport( _atsContextFactory.GetContext(), [packageName]); diff --git a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs index 3cca83b5cdf..20138f444ae 100644 --- a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs +++ b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs @@ -7,12 +7,11 @@ namespace Aspire.TypeSystem; /// Describes the package identity and ownership scope of an export. /// /// -/// The ATS context handed to an exporter is already filtered to the exporting assemblies plus their -/// reference closure, because the generated code does not type-check without the referenced -/// declarations. That closure is exactly why exists: it lets the -/// exporter tell apart symbols the package owns and should document from symbols it merely needs to -/// emit so the output is self-contained. Without it, every package would republish its dependencies' -/// API reference. +/// The ATS context handed to an exporter is already filtered to the exporting assemblies, their +/// reference closure, and the reduced member shapes needed to resolve wrappers for referenced handle +/// types. That closure is exactly why exists: it lets the exporter +/// tell apart symbols the package owns and should document from symbols it merely needs to emit so the +/// output is self-contained. Without it, every package would republish its dependencies' API reference. /// public sealed class ApiReferenceExportOptions { diff --git a/src/Aspire.TypeSystem/AtsContext.cs b/src/Aspire.TypeSystem/AtsContext.cs index 29722166100..6fd06279613 100644 --- a/src/Aspire.TypeSystem/AtsContext.cs +++ b/src/Aspire.TypeSystem/AtsContext.cs @@ -98,6 +98,17 @@ public sealed class AtsContext /// public Dictionary Properties { get; } = new(); + /// + /// Gets the assemblies that exported each capability, keyed by capability ID. + /// + /// + /// The declaring CLR type can belong to another assembly when an assembly-level + /// AspireExport exposes an external type, so reflection alone cannot determine + /// which package owns the exported capability. + /// + public IReadOnlyDictionary CapabilityExportingAssemblyNames { get; init; } = + new Dictionary(); + /// /// Gets the type category for a CLR type based on scanned data. /// Used at runtime for marshalling. diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index a81af76aee8..aba53e55bda 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1128,15 +1128,29 @@ private static AtsContext CreateContextFromTestAssembly() private static AtsContext WithAdditionalCapabilities(AtsContext context, params AtsCapabilityInfo[] capabilities) { - return new AtsContext + var result = new AtsContext { Capabilities = [.. context.Capabilities, .. capabilities], HandleTypes = context.HandleTypes, DtoTypes = context.DtoTypes, EnumTypes = context.EnumTypes, ExportedValues = context.ExportedValues, - Diagnostics = context.Diagnostics + Diagnostics = context.Diagnostics, + CapabilityExportingAssemblyNames = context.CapabilityExportingAssemblyNames + .Concat(capabilities.Select(capability => + new KeyValuePair(capability.CapabilityId, TestPackageName))) + .ToDictionary(static pair => pair.Key, static pair => pair.Value, StringComparer.Ordinal) }; + + foreach (var (id, method) in context.Methods) + { + result.Methods[id] = method; + } + foreach (var (id, property) in context.Properties) + { + result.Properties[id] = property; + } + return result; } private static AtsCapabilityInfo CreateDistributedApplicationBuilderCapability( @@ -1979,6 +1993,22 @@ AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] IsOptional = true, Documentation = new AtsDocumentationInfo { Summary = "Whether the behavior is enabled." } }), + CreateCapability( + "withOptionalOptionsField", + new AtsParameterInfo + { + Name = "options", + Type = stringParameter.Type, + IsOptional = true, + Documentation = new AtsDocumentationInfo { Summary = "An optional value stored in the generated options bag." } + }, + new AtsParameterInfo + { + Name = "enabled", + Type = boolParameter.Type, + IsOptional = true, + Documentation = new AtsDocumentationInfo { Summary = "Whether the behavior is enabled." } + }), CreateCapability( "withDirectOptionsAndCancellation", new AtsParameterInfo @@ -2023,6 +2053,16 @@ AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] parameter => AssertParameter(parameter, "optionsBag", "string", isOptional: false, "Required options bag value."), parameter => AssertParameter(parameter, "_optionsBag", "WithOptionsCollisionOptions", isOptional: true)); + var withOptionalOptionsField = Assert.Single( + testRedisResource.Members, + member => member.Name == "withOptionalOptionsField"); + Assert.Equal( + "withOptionalOptionsField(options?: WithOptionalOptionsFieldOptions): Promise", + withOptionalOptionsField.Declaration); + Assert.Collection( + withOptionalOptionsField.Parameters, + parameter => AssertParameter(parameter, "options", "WithOptionalOptionsFieldOptions", isOptional: true)); + var withDirectOptionsAndCancellation = Assert.Single( testRedisResource.Members, member => member.Name == "withDirectOptionsAndCancellation"); @@ -2040,7 +2080,13 @@ AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] var testRedisResourceMembers = generatedInterfaceMembers[nameof(TestRedisResource)]; Assert.Contains(withOptionsCollision.Declaration, testRedisResourceMembers); + Assert.Contains(withOptionalOptionsField.Declaration, testRedisResourceMembers); Assert.Contains(withDirectOptionsAndCancellation.Declaration, testRedisResourceMembers); + Assert.Contains( + "async withOptionalOptionsField(optionsBag?: WithOptionalOptionsFieldOptions): Promise {", + generatedSource); + Assert.Contains("const options = optionsBag?.options;", generatedSource); + Assert.DoesNotContain("const options = options?.options;", generatedSource); static void AssertParameter( TypeScriptApiParameter parameter, @@ -2209,6 +2255,115 @@ public void ApiExportDeclarationsAppearInGeneratedPublicInterfaces() Assert.True(checkedDeclarations > 0, "The canonical export produced no method declarations to compare."); } + [Fact] + public void ApiExportUsesPromiseWrappersFromReferencedHandleCapabilities() + { + var fullContext = CreateReferencedHandleContext(); + var exportContext = AtsContextFilter.FilterForApiExport( + fullContext, + [TestPackageName]); + + var projector = new TypeScriptApiProjector(exportContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var ownedContext = Assert.Single( + model.Modules.SelectMany(module => module.Items), + item => item.Name == "OwnedContext"); + var exportedMethod = Assert.Single( + ownedContext.Members, + member => member.Name == "getForeign"); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(fullContext)["aspire.mts"]; + var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); + + Assert.Contains(exportedMethod.Declaration, generatedInterfaceMembers["OwnedContext"]); + } + + [Fact] + public void ApiExportUsesResourceWrappersReferencedOnlyBySupportingCapabilities() + { + var fullContext = CreateReferencedHandleContext(); + var exportContext = AtsContextFilter.FilterForApiExport( + fullContext, + [TestPackageName]); + + var projector = new TypeScriptApiProjector(exportContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var ownedContext = Assert.Single( + model.Modules.SelectMany(module => module.Items), + item => item.Name == "OwnedContext"); + var exportedMethod = Assert.Single( + ownedContext.Members, + member => member.Name == "waitFor"); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(fullContext)["aspire.mts"]; + var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); + + Assert.Contains(exportedMethod.Declaration, generatedInterfaceMembers["OwnedContext"]); + } + + [Fact] + public void ApiExportRetainsExpandedTargetsFromSupportingCapabilities() + { + var fullContext = CreateReferencedHandleContext(); + var exportContext = AtsContextFilter.FilterForApiExport( + fullContext, + [TestPackageName]); + + var projector = new TypeScriptApiProjector(exportContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + [TestPackageName]); + + var ownedContext = Assert.Single( + model.Modules.SelectMany(module => module.Items), + item => item.Name == "OwnedContext"); + var exportedMethod = Assert.Single( + ownedContext.Members, + member => member.Name == "waitForForeign"); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(fullContext)["aspire.mts"]; + var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); + + Assert.Contains(exportedMethod.Declaration, generatedInterfaceMembers["OwnedContext"]); + Assert.Equal( + exportContext.Capabilities.Count, + exportContext.Capabilities.Select(capability => capability.CapabilityId).Distinct(StringComparer.Ordinal).Count()); + } + + [Fact] + public void ApiExportRetainsAssemblyOwnedMembersOnExternalTypes() + { + var fullContext = CreateContextFromBothAssemblies(); + var exportContext = AtsContextFilter.FilterForApiExport( + fullContext, + ["Aspire.Hosting"]); + + var projector = new TypeScriptApiProjector(exportContext); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity("Aspire.Hosting", TestPackageVersion), + ["Aspire.Hosting"]); + var items = model.Modules.SelectMany(module => module.Items).ToList(); + + var configurationSection = Assert.Single(items, item => item.Name == "ConfigurationSection"); + Assert.Contains(configurationSection.Members, member => member.Name == "key"); + Assert.Contains(configurationSection.Members, member => member.Name == "path"); + Assert.Contains(configurationSection.Members, member => member.Name == "value"); + + var hostEnvironment = Assert.Single(items, item => item.Name == "HostEnvironment"); + Assert.Contains(hostEnvironment.Members, member => member.Name == "applicationName"); + Assert.Contains(hostEnvironment.Members, member => member.Name == "environmentName"); + Assert.Contains(hostEnvironment.Members, member => member.Name == "contentRootPath"); + } + /// /// DTO interfaces carry properties that have no C# counterpart, such as the client-only /// throwOnPendingRejections on CreateBuilderOptions. Those used to be appended by the @@ -2362,11 +2517,231 @@ public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() /// private static AtsContext CreateOwnershipFilteredContext() { - return AtsContextFilter.FilterByExportingAssembliesWithReferences( + return AtsContextFilter.FilterForApiExport( CreateContextFromBothAssemblies(), [TestPackageName]); } + private static AtsContext CreateReferencedHandleContext() + { + const string ownedTypeId = TestPackageName + "/IOwnedContext"; + const string foreignTypeId = "Foreign.Dependency/IForeignHandle"; + const string resourceTypeId = "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource"; + const string foreignResourceTypeId = "Foreign.Dependency/ForeignResource"; + const string secondForeignResourceTypeId = "Foreign.Dependency/SecondForeignResource"; + const string parameterResourceTypeId = "Foreign.Dependency/ParameterResource"; + const string callbackParameterResourceTypeId = "Foreign.Dependency/CallbackParameterResource"; + const string callbackReturnResourceTypeId = "Foreign.Dependency/CallbackReturnResource"; + const string returnResourceTypeId = "Foreign.Dependency/ReturnResource"; + + var ownedType = new AtsTypeRef + { + TypeId = ownedTypeId, + Category = AtsTypeCategory.Handle, + IsInterface = true + }; + var foreignType = new AtsTypeRef + { + TypeId = foreignTypeId, + Category = AtsTypeCategory.Handle, + IsInterface = true + }; + var resourceType = new AtsTypeRef + { + TypeId = resourceTypeId, + Category = AtsTypeCategory.Handle, + ClrType = typeof(IResource), + IsInterface = true + }; + var foreignResourceType = new AtsTypeRef + { + TypeId = foreignResourceTypeId, + Category = AtsTypeCategory.Handle, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = [resourceType, foreignType] + }; + var secondForeignResourceType = CreateResourceType(secondForeignResourceTypeId, resourceType, foreignType); + var parameterResourceType = CreateResourceType(parameterResourceTypeId, resourceType); + var callbackParameterResourceType = CreateResourceType(callbackParameterResourceTypeId, resourceType); + var callbackReturnResourceType = CreateResourceType(callbackReturnResourceTypeId, resourceType); + var returnResourceType = CreateResourceType(returnResourceTypeId, resourceType); + + return new AtsContext + { + Capabilities = + [ + new AtsCapabilityInfo + { + CapabilityId = TestPackageName + "/getForeign", + MethodName = "getForeign", + OwningTypeName = "IOwnedContext", + Parameters = [], + ReturnType = foreignType, + TargetTypeId = ownedTypeId, + TargetType = ownedType, + ReturnsBuilder = false, + CapabilityKind = AtsCapabilityKind.InstanceMethod + }, + new AtsCapabilityInfo + { + CapabilityId = TestPackageName + "/getConcrete", + MethodName = "getConcrete", + OwningTypeName = "IOwnedContext", + Parameters = [], + ReturnType = foreignResourceType, + TargetTypeId = ownedTypeId, + TargetType = ownedType, + ReturnsBuilder = false, + CapabilityKind = AtsCapabilityKind.InstanceMethod + }, + new AtsCapabilityInfo + { + CapabilityId = TestPackageName + "/waitFor", + MethodName = "waitFor", + OwningTypeName = "IOwnedContext", + Parameters = + [ + new AtsParameterInfo + { + Name = "dependency", + Type = resourceType + } + ], + ReturnType = new AtsTypeRef + { + TypeId = AtsConstants.Void, + Category = AtsTypeCategory.Primitive + }, + TargetTypeId = ownedTypeId, + TargetType = ownedType, + ReturnsBuilder = false, + CapabilityKind = AtsCapabilityKind.InstanceMethod + }, + new AtsCapabilityInfo + { + CapabilityId = TestPackageName + "/waitForForeign", + MethodName = "waitForForeign", + OwningTypeName = "IOwnedContext", + Parameters = + [ + new AtsParameterInfo + { + Name = "dependency", + Type = foreignType + } + ], + ReturnType = new AtsTypeRef + { + TypeId = AtsConstants.Void, + Category = AtsTypeCategory.Primitive + }, + TargetTypeId = ownedTypeId, + TargetType = ownedType, + ReturnsBuilder = false, + CapabilityKind = AtsCapabilityKind.InstanceMethod + }, + new AtsCapabilityInfo + { + CapabilityId = "Foreign.Dependency/getName", + MethodName = "getName", + OwningTypeName = "IForeignHandle", + Parameters = + [ + new AtsParameterInfo + { + Name = "resource", + Type = parameterResourceType + }, + new AtsParameterInfo + { + Name = "configure", + IsCallback = true, + CallbackParameters = + [ + new AtsCallbackParameterInfo + { + Name = "resource", + Type = callbackParameterResourceType + } + ], + CallbackReturnType = callbackReturnResourceType + } + ], + ReturnType = returnResourceType, + TargetTypeId = foreignTypeId, + TargetType = foreignType, + ExpandedTargetTypes = [foreignResourceType, secondForeignResourceType], + ReturnsBuilder = false, + CapabilityKind = AtsCapabilityKind.InstanceMethod + } + ], + HandleTypes = + [ + new AtsTypeInfo + { + AtsTypeId = ownedTypeId, + IsInterface = true + }, + new AtsTypeInfo + { + AtsTypeId = foreignTypeId, + IsInterface = true + }, + new AtsTypeInfo + { + AtsTypeId = foreignResourceTypeId, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = [resourceType, foreignType] + }, + new AtsTypeInfo + { + AtsTypeId = secondForeignResourceTypeId, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = [resourceType, foreignType] + }, + new AtsTypeInfo + { + AtsTypeId = parameterResourceTypeId, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = [resourceType] + }, + new AtsTypeInfo + { + AtsTypeId = callbackParameterResourceTypeId, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = [resourceType] + }, + new AtsTypeInfo + { + AtsTypeId = callbackReturnResourceTypeId, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = [resourceType] + }, + new AtsTypeInfo + { + AtsTypeId = returnResourceTypeId, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = [resourceType] + } + ], + DtoTypes = [], + EnumTypes = [] + }; + + static AtsTypeRef CreateResourceType(string typeId, AtsTypeRef resourceType, AtsTypeRef? additionalInterface = null) + { + return new AtsTypeRef + { + TypeId = typeId, + Category = AtsTypeCategory.Handle, + ClrType = typeof(TestRedisResource), + ImplementedInterfaces = additionalInterface is null + ? [resourceType] + : [resourceType, additionalInterface] + }; + } + } + /// /// Extracts the member signature lines of every generated export interface block. /// diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index 7627efd9a44..7016f39b689 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -10,7 +10,7 @@ export interface CSharpAppResource { withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; - testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; + testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; withDependency(dependency: Awaitable): CSharpAppResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): CSharpAppResourcePromise; withEndpoints(endpoints: string[]): CSharpAppResourcePromise; @@ -38,7 +38,7 @@ export interface CSharpAppResourcePromise { withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; - testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; + testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; withDependency(dependency: Awaitable): CSharpAppResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): CSharpAppResourcePromise; withEndpoints(endpoints: string[]): CSharpAppResourcePromise; @@ -65,7 +65,7 @@ export interface ContainerRegistryResource { withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; - testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; + testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; withDependency(dependency: Awaitable): ContainerRegistryResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerRegistryResourcePromise; withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise; @@ -91,7 +91,7 @@ export interface ContainerRegistryResourcePromise { withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; - testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; + testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; withDependency(dependency: Awaitable): ContainerRegistryResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerRegistryResourcePromise; withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise; @@ -118,7 +118,7 @@ export interface ContainerResource { withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; - testWaitFor(dependency: Awaitable): ContainerResourcePromise; + testWaitFor(dependency: Awaitable): ContainerResourcePromise; withDependency(dependency: Awaitable): ContainerResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerResourcePromise; withEndpoints(endpoints: string[]): ContainerResourcePromise; @@ -146,7 +146,7 @@ export interface ContainerResourcePromise { withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; - testWaitFor(dependency: Awaitable): ContainerResourcePromise; + testWaitFor(dependency: Awaitable): ContainerResourcePromise; withDependency(dependency: Awaitable): ContainerResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerResourcePromise; withEndpoints(endpoints: string[]): ContainerResourcePromise; @@ -186,7 +186,7 @@ export interface DotnetToolResource { withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; - testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; + testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; withDependency(dependency: Awaitable): DotnetToolResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): DotnetToolResourcePromise; withEndpoints(endpoints: string[]): DotnetToolResourcePromise; @@ -214,7 +214,7 @@ export interface DotnetToolResourcePromise { withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; - testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; + testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; withDependency(dependency: Awaitable): DotnetToolResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): DotnetToolResourcePromise; withEndpoints(endpoints: string[]): DotnetToolResourcePromise; @@ -242,7 +242,7 @@ export interface ExecutableResource { withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; - testWaitFor(dependency: Awaitable): ExecutableResourcePromise; + testWaitFor(dependency: Awaitable): ExecutableResourcePromise; withDependency(dependency: Awaitable): ExecutableResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExecutableResourcePromise; withEndpoints(endpoints: string[]): ExecutableResourcePromise; @@ -270,7 +270,7 @@ export interface ExecutableResourcePromise { withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; - testWaitFor(dependency: Awaitable): ExecutableResourcePromise; + testWaitFor(dependency: Awaitable): ExecutableResourcePromise; withDependency(dependency: Awaitable): ExecutableResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExecutableResourcePromise; withEndpoints(endpoints: string[]): ExecutableResourcePromise; @@ -297,7 +297,7 @@ export interface ExternalServiceResource { withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; - testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; + testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; withDependency(dependency: Awaitable): ExternalServiceResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExternalServiceResourcePromise; withEndpoints(endpoints: string[]): ExternalServiceResourcePromise; @@ -323,7 +323,7 @@ export interface ExternalServiceResourcePromise { withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; - testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; + testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; withDependency(dependency: Awaitable): ExternalServiceResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExternalServiceResourcePromise; withEndpoints(endpoints: string[]): ExternalServiceResourcePromise; @@ -349,7 +349,7 @@ export interface ParameterResource { withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; - testWaitFor(dependency: Awaitable): ParameterResourcePromise; + testWaitFor(dependency: Awaitable): ParameterResourcePromise; withDependency(dependency: Awaitable): ParameterResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ParameterResourcePromise; withEndpoints(endpoints: string[]): ParameterResourcePromise; @@ -375,7 +375,7 @@ export interface ParameterResourcePromise { withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; - testWaitFor(dependency: Awaitable): ParameterResourcePromise; + testWaitFor(dependency: Awaitable): ParameterResourcePromise; withDependency(dependency: Awaitable): ParameterResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ParameterResourcePromise; withEndpoints(endpoints: string[]): ParameterResourcePromise; @@ -402,7 +402,7 @@ export interface ProjectResource { withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; - testWaitFor(dependency: Awaitable): ProjectResourcePromise; + testWaitFor(dependency: Awaitable): ProjectResourcePromise; withDependency(dependency: Awaitable): ProjectResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ProjectResourcePromise; withEndpoints(endpoints: string[]): ProjectResourcePromise; @@ -430,7 +430,7 @@ export interface ProjectResourcePromise { withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; - testWaitFor(dependency: Awaitable): ProjectResourcePromise; + testWaitFor(dependency: Awaitable): ProjectResourcePromise; withDependency(dependency: Awaitable): ProjectResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ProjectResourcePromise; withEndpoints(endpoints: string[]): ProjectResourcePromise; @@ -457,7 +457,7 @@ export interface Resource { withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; - testWaitFor(dependency: Awaitable): ResourcePromise; + testWaitFor(dependency: Awaitable): ResourcePromise; withDependency(dependency: Awaitable): ResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ResourcePromise; withEndpoints(endpoints: string[]): ResourcePromise; @@ -483,7 +483,7 @@ export interface ResourcePromise { withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; - testWaitFor(dependency: Awaitable): ResourcePromise; + testWaitFor(dependency: Awaitable): ResourcePromise; withDependency(dependency: Awaitable): ResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ResourcePromise; withEndpoints(endpoints: string[]): ResourcePromise; @@ -596,7 +596,7 @@ export interface TestDatabaseResource extends ResourceBuilderBase { withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; - testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; + testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; withDependency(dependency: Awaitable): TestDatabaseResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestDatabaseResourcePromise; withEndpoints(endpoints: string[]): TestDatabaseResourcePromise; @@ -624,7 +624,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike Promise): TestDatabaseResourcePromise; - testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; + testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; withDependency(dependency: Awaitable): TestDatabaseResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestDatabaseResourcePromise; withEndpoints(endpoints: string[]): TestDatabaseResourcePromise; @@ -673,7 +673,7 @@ export interface TestRedisResource extends ResourceBuilderBase { withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; - testWaitFor(dependency: Awaitable): TestRedisResourcePromise; + testWaitFor(dependency: Awaitable): TestRedisResourcePromise; getEndpoints(): Promise; withConnectionStringDirect(connectionString: string): TestRedisResourcePromise; withRedisSpecific(option: string): TestRedisResourcePromise; @@ -713,7 +713,7 @@ export interface TestRedisResourcePromise extends PromiseLike withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; - testWaitFor(dependency: Awaitable): TestRedisResourcePromise; + testWaitFor(dependency: Awaitable): TestRedisResourcePromise; getEndpoints(): Promise; withConnectionStringDirect(connectionString: string): TestRedisResourcePromise; withRedisSpecific(option: string): TestRedisResourcePromise; @@ -768,7 +768,7 @@ export interface TestVaultResource extends ResourceBuilderBase { withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; - testWaitFor(dependency: Awaitable): TestVaultResourcePromise; + testWaitFor(dependency: Awaitable): TestVaultResourcePromise; withDependency(dependency: Awaitable): TestVaultResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestVaultResourcePromise; withEndpoints(endpoints: string[]): TestVaultResourcePromise; @@ -797,7 +797,7 @@ export interface TestVaultResourcePromise extends PromiseLike withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; - testWaitFor(dependency: Awaitable): TestVaultResourcePromise; + testWaitFor(dependency: Awaitable): TestVaultResourcePromise; withDependency(dependency: Awaitable): TestVaultResourcePromise; withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestVaultResourcePromise; withEndpoints(endpoints: string[]): TestVaultResourcePromise; @@ -868,9 +868,21 @@ export interface WithPersistenceOptions { mode?: TestPersistenceMode; } +// Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle +export type CommandLineArgsCallbackContextHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.CommandLineArgsCallbackContext'>; + +// Aspire.Hosting:handle:EndpointReferenceHandle +export type EndpointReferenceHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointReference'>; + +// Aspire.Hosting:handle:EndpointUpdateContextHandle +export type EndpointUpdateContextHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointUpdateContext'>; + // Aspire.Hosting:handle:ReferenceExpressionHandle export type ReferenceExpressionHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.ReferenceExpression'>; +// Aspire.Hosting:handle:ResourceEndpointsAllocatedEventHandle +export type ResourceEndpointsAllocatedEventHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.ResourceEndpointsAllocatedEvent'>; + // Aspire.Hosting:opaque:CSharpAppResource export interface CSharpAppResource extends ResourceBuilderBase {} @@ -931,18 +943,36 @@ export interface Resource extends ResourceBuilderBase {} // Aspire.Hosting:opaque:ResourcePromise export interface ResourcePromise extends PromiseLike {} +// Aspire.Hosting:opaque:ResourceWithArgs +export interface ResourceWithArgs extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ResourceWithArgsPromise +export interface ResourceWithArgsPromise extends PromiseLike {} + // Aspire.Hosting:opaque:ResourceWithConnectionString export interface ResourceWithConnectionString extends ResourceBuilderBase {} // Aspire.Hosting:opaque:ResourceWithConnectionStringPromise export interface ResourceWithConnectionStringPromise extends PromiseLike {} +// Aspire.Hosting:opaque:ResourceWithEndpoints +export interface ResourceWithEndpoints extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ResourceWithEndpointsPromise +export interface ResourceWithEndpointsPromise extends PromiseLike {} + // Aspire.Hosting:opaque:ResourceWithEnvironment export interface ResourceWithEnvironment extends ResourceBuilderBase {} // Aspire.Hosting:opaque:ResourceWithEnvironmentPromise export interface ResourceWithEnvironmentPromise extends PromiseLike {} +// Aspire.Hosting:opaque:ResourceWithWaitSupport +export interface ResourceWithWaitSupport extends ResourceBuilderBase {} + +// Aspire.Hosting:opaque:ResourceWithWaitSupportPromise +export interface ResourceWithWaitSupportPromise extends PromiseLike {} + // aspire:runtime:base export type Awaitable = T | PromiseLike; export interface MarshalledHandle { $handle: string; $type: string; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index cb8fb7fe5d5..eb41cd410c3 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -184,14 +184,14 @@ "id": "method:CSharpAppResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "CSharpAppResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -635,14 +635,14 @@ "id": "method:ContainerRegistryResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "ContainerRegistryResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -1087,14 +1087,14 @@ "id": "method:ContainerResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "ContainerResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -1603,14 +1603,14 @@ "id": "method:DotnetToolResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "DotnetToolResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -2072,14 +2072,14 @@ "id": "method:ExecutableResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "ExecutableResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -2523,14 +2523,14 @@ "id": "method:ExternalServiceResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "ExternalServiceResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -2959,14 +2959,14 @@ "id": "method:ParameterResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "ParameterResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -3411,14 +3411,14 @@ "id": "method:ProjectResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "ProjectResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -3863,14 +3863,14 @@ "id": "method:Resource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "ResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -4633,14 +4633,14 @@ "id": "method:TestDatabaseResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "TestDatabaseResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -5228,14 +5228,14 @@ "id": "method:TestRedisResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "TestRedisResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -5864,14 +5864,14 @@ "id": "method:TestVaultResource.testWaitFor", "kind": "method", "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise", + "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", "returnType": "TestVaultResourcePromise", "summary": "Waits for another resource (test version)", "parameters": [ { "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", + "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", "optional": false } ] @@ -6363,32 +6363,32 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResource {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResource {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder", @@ -6403,62 +6403,62 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResource {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResource {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResource {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResource {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResource {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResource {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResource {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResource {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResource {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResource {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Resource {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface Resource {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface ResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString", @@ -6528,12 +6528,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext", @@ -6548,12 +6548,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", @@ -6568,12 +6568,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithConnectionString | ResourceWithEnvironment | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions", @@ -6625,11 +6625,31 @@ "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", "content": "export interface WithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" }, + { + "id": "Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle", + "owningAssembly": "Aspire.Hosting", + "content": "export type CommandLineArgsCallbackContextHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.CommandLineArgsCallbackContext\u0027\u003E;" + }, + { + "id": "Aspire.Hosting:handle:EndpointReferenceHandle", + "owningAssembly": "Aspire.Hosting", + "content": "export type EndpointReferenceHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointReference\u0027\u003E;" + }, + { + "id": "Aspire.Hosting:handle:EndpointUpdateContextHandle", + "owningAssembly": "Aspire.Hosting", + "content": "export type EndpointUpdateContextHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointUpdateContext\u0027\u003E;" + }, { "id": "Aspire.Hosting:handle:ReferenceExpressionHandle", "owningAssembly": "Aspire.Hosting", "content": "export type ReferenceExpressionHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.ReferenceExpression\u0027\u003E;" }, + { + "id": "Aspire.Hosting:handle:ResourceEndpointsAllocatedEventHandle", + "owningAssembly": "Aspire.Hosting", + "content": "export type ResourceEndpointsAllocatedEventHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.ResourceEndpointsAllocatedEvent\u0027\u003E;" + }, { "id": "Aspire.Hosting:opaque:CSharpAppResource", "owningAssembly": "Aspire.Hosting", @@ -6730,6 +6750,16 @@ "owningAssembly": "Aspire.Hosting", "content": "export interface ResourcePromise extends PromiseLike\u003CResource\u003E {}" }, + { + "id": "Aspire.Hosting:opaque:ResourceWithArgs", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithArgs extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourceWithArgsPromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithArgsPromise extends PromiseLike\u003CResourceWithArgs\u003E {}" + }, { "id": "Aspire.Hosting:opaque:ResourceWithConnectionString", "owningAssembly": "Aspire.Hosting", @@ -6740,6 +6770,16 @@ "owningAssembly": "Aspire.Hosting", "content": "export interface ResourceWithConnectionStringPromise extends PromiseLike\u003CResourceWithConnectionString\u003E {}" }, + { + "id": "Aspire.Hosting:opaque:ResourceWithEndpoints", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithEndpoints extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourceWithEndpointsPromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithEndpointsPromise extends PromiseLike\u003CResourceWithEndpoints\u003E {}" + }, { "id": "Aspire.Hosting:opaque:ResourceWithEnvironment", "owningAssembly": "Aspire.Hosting", @@ -6750,6 +6790,16 @@ "owningAssembly": "Aspire.Hosting", "content": "export interface ResourceWithEnvironmentPromise extends PromiseLike\u003CResourceWithEnvironment\u003E {}" }, + { + "id": "Aspire.Hosting:opaque:ResourceWithWaitSupport", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithWaitSupport extends ResourceBuilderBase {}" + }, + { + "id": "Aspire.Hosting:opaque:ResourceWithWaitSupportPromise", + "owningAssembly": "Aspire.Hosting", + "content": "export interface ResourceWithWaitSupportPromise extends PromiseLike\u003CResourceWithWaitSupport\u003E {}" + }, { "id": "aspire:runtime:base", "owningAssembly": "Aspire.Hosting", diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index a82d4da80b5..145561acd67 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -71,6 +71,71 @@ public void FilterByExportingAssemblies_CodeGenerationFilterIncludesReferencedSu Assert.DoesNotContain(filteredContext.HandleTypes, type => type.AtsTypeId == "Aspire.Hosting/Aspire.Hosting.DistributedApplication"); } + [Fact] + public void FilterForApiExport_IncludesOnlyReferencedHandleCapabilityShape() + { + var context = CreateContext(); + var referencedHandleType = Assert.Single( + context.HandleTypes, + type => type.AtsTypeId == "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ResourceBuilder`1"); + var supportingCapability = new AtsCapabilityInfo + { + CapabilityId = "Aspire.Hosting/getResourceName", + MethodName = "getResourceName", + Parameters = + [ + new AtsParameterInfo + { + Name = "unused", + Type = new AtsTypeRef + { + TypeId = "Aspire.TypeSystem/AtsContext", + Category = AtsTypeCategory.Dto + } + } + ], + ReturnType = new AtsTypeRef + { + TypeId = "Aspire.Hosting/Aspire.Hosting.DistributedApplication", + Category = AtsTypeCategory.Handle + }, + TargetTypeId = referencedHandleType.AtsTypeId, + TargetType = new AtsTypeRef + { + TypeId = referencedHandleType.AtsTypeId, + ClrType = referencedHandleType.ClrType, + Category = AtsTypeCategory.Handle, + IsInterface = true + }, + CapabilityKind = AtsCapabilityKind.InstanceMethod + }; + context = new AtsContext + { + Capabilities = [.. context.Capabilities, supportingCapability], + HandleTypes = context.HandleTypes, + DtoTypes = context.DtoTypes, + EnumTypes = context.EnumTypes, + ExportedValues = context.ExportedValues, + Diagnostics = context.Diagnostics + }; + + var filteredContext = AtsContextFilter.FilterForApiExport( + context, + [typeof(AtsContextFilterTests).Assembly.GetName().Name!]); + + var filteredSupport = Assert.Single( + filteredContext.Capabilities, + capability => capability.CapabilityId == supportingCapability.CapabilityId); + var supportParameter = Assert.Single(filteredSupport.Parameters); + Assert.False(supportParameter.IsOptional); + Assert.Equal("Aspire.Hosting/Aspire.Hosting.DistributedApplication", supportParameter.Type?.TypeId); + Assert.Equal(AtsConstants.Void, filteredSupport.ReturnType.TypeId); + Assert.Equal(referencedHandleType.AtsTypeId, filteredSupport.TargetTypeId); + Assert.DoesNotContain( + filteredContext.Capabilities, + capability => capability.CapabilityId == "Aspire.Hosting/createBuilder"); + } + [Fact] public void FilterByExportingAssemblies_CodeGenerationFilterExpandsOwnedDtoPropertyTypes() { From e60688669dc6bd8d329e44b60cbb130859e865a9 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 05:34:11 -0400 Subject: [PATCH 16/73] Make sdk export restore the version it labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three suppressed Copilot review comments on #19032 all pointed at the same thing from different angles: the export document carries a package version that nothing was making true. `sdk export Package@Version` could publish a surface that was not that version's, two ways. A CLI run from a repository checkout picks `DotNetBasedAppHostServerProject`, which replaces every first-party `Aspire.Hosting.*` package reference with the matching project under `src/` and throws the requested version away, so asking a 13.5.0 checkout for 13.4.0 exported the checkout under the older number. Separately, a bare NuGet version is a minimum rather than an equality, so a version missing from the feed quietly restored as the next one up. Both are now narrow contracts on the export path. `IntegrationReference` carries `RequireExactVersion`, and `sdk export` sets it on the requested package so the restore fails (NU1102) instead of resolving upward. `IAppHostServerProject.GetLocalProjectSubstitution` reports the substitution a checkout would make, and `sdk export` refuses a version the checkout would not actually produce. Same-version local development, third-party exports, `--source` pinning, the core-package guard, and code generator restoration are all unchanged, and run/dump keep the minimum-version form that lets transitive dependencies unify. `ApiReferenceExportOptions` gains the `` documentation repo policy requires, and `PackageVersion` stops promising exactness it cannot enforce. Validating it in the DTO would mean either a new package reference in a contract assembly that deliberately has none, or a hand-rolled partial range check — and neither can tell an exact-but-wrong version from a right one. The docs now say the caller owns accuracy and point at `sdk export`, where the restore is actually decided. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ffeff87e-f284-434d-87d3-843e21a7aebb --- .../Commands/Sdk/SdkCommandPreparation.cs | 24 +++ src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs | 2 + .../Commands/Sdk/SdkExportCommand.cs | 55 ++++++- .../Configuration/IntegrationReference.cs | 55 +++++++ .../DotNetBasedAppHostServerProject.cs | 28 +++- .../Projects/IAppHostServerProject.cs | 13 ++ .../Projects/PrebuiltAppHostServer.cs | 18 +-- .../CodeGeneration/CodeGenerationService.cs | 5 +- .../ApiReferenceExportOptions.cs | 23 ++- .../Commands/Sdk/SdkExportCommandTests.cs | 90 +++++++++++ ...BasedAppHostServerPackageReferenceTests.cs | 151 +++++++++++++++--- .../Projects/PrebuiltAppHostServerTests.cs | 21 +++ .../FakeSucceedingAppHostServerProject.cs | 11 ++ 13 files changed, 456 insertions(+), 40 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs index d1523903908..fa554b28991 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs @@ -120,6 +120,23 @@ public static bool TryParseIntegrationArgument( /// and surface as a null session rather than an exception, /// because a failed restore is a user-facing outcome and not a bug. /// + /// Creates the scanner AppHost for the temporary directory. + /// Creates the session that runs the scanner AppHost. + /// Reports build failures and rejections to the user. + /// Receives diagnostic detail about the preparation. + /// Prefix for the throwaway project directory. + /// The Aspire SDK version the scanner AppHost is restored at. + /// The integrations to restore into the scanner AppHost. + /// A NuGet source to prefer, or for the configured sources. + /// + /// A pre-flight check run against the created server project before anything is restored, or + /// when the caller has nothing to check. Returning a message rejects the + /// request and reports it through . This exists because the + /// factory only decides between the repository and prebuilt servers once the project is created, + /// and sdk export has to refuse a package the repository server would build from the + /// current checkout instead of restoring at the requested version. + /// + /// Cancellation token. public static async Task PrepareSessionAsync( IAppHostServerProjectFactory appHostServerProjectFactory, IAppHostServerSessionFactory serverSessionFactory, @@ -129,6 +146,7 @@ public static bool TryParseIntegrationArgument( string sdkVersion, IReadOnlyList integrations, string? packageSourceOverride, + Func? validateProject, CancellationToken cancellationToken) { var tempDirectory = Directory.CreateTempSubdirectory(tempDirectoryPrefix); @@ -139,6 +157,12 @@ public static bool TryParseIntegrationArgument( { var appHostServerProject = await appHostServerProjectFactory.CreateAsync(tempDir, cancellationToken); + if (validateProject?.Invoke(appHostServerProject) is string rejection) + { + interactionService.DisplayError(rejection); + return null; + } + logger.LogDebug("Building AppHost server with {Count} integrations", integrations.Count); var prepareResult = await appHostServerProject.PrepareAsync( diff --git a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs index 2f0308ee440..b94689a6a5c 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs @@ -148,6 +148,7 @@ private async Task DumpCapabilitiesAsync( ExecutionContext.IdentityVersion, integrations, packageSourceOverride: null, + validateProject: null, cancellationToken); if (session is null) @@ -209,6 +210,7 @@ private async Task DumpCapabilitiesToDirectoryAsync( ExecutionContext.IdentityVersion, integrations, packageSourceOverride: null, + validateProject: null, cancellationToken); if (session is null) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 59616265a09..9ac0511e8d6 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -137,7 +137,9 @@ protected override async Task ExecuteAsync(ParseResult parseResul } else { - integrations.Add(reference); + // Pin the requested version: a bare NuGet version is a minimum, so an unavailable + // version would restore as a later one and be published under the wrong number. + integrations.Add(IntegrationReference.FromExactPackage(reference.Name, reference.Version)); } } @@ -199,6 +201,48 @@ private static string StripBuildMetadata(string version) return plusIndex < 0 ? version : version[..plusIndex]; } + /// + /// Refuses an export the scanner would satisfy from a local checkout instead of restoring the + /// requested package version. + /// + /// + /// In repository development mode the scanner AppHost replaces every first-party + /// Aspire.Hosting.* package reference with the matching project under src/ and + /// discards the requested version, so the checkout's API surface would be published under + /// someone else's version number. That is the same stale-signature problem the core-package + /// guard prevents, so this refuses for the same reason. Asking for the version this CLI was + /// built from is still allowed: that is exactly what the checkout contains. The core package is + /// already handled before any project is created, and third-party packages are never + /// substituted, so both fall straight through. + /// + /// The scanner AppHost that will restore the export. + /// The package being exported. + /// The version the caller asked for. + /// The rejection reason, or when the request is exportable. + private string? ValidateRequestedPackageIsRestorable(IAppHostServerProject serverProject, string packageName, string packageVersion) + { + if (string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + if (serverProject.GetLocalProjectSubstitution(packageName) is not string localProjectPath) + { + return null; + } + + var requested = StripBuildMetadata(packageVersion); + if (string.Equals(requested, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + return $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {localProjectPath} " + + $"instead of being restored from a package feed. That checkout is {ExecutionContext.IdentitySdkVersion}, " + + $"but {packageVersion} was requested, and exporting it would describe the checkout's API surface under the " + + $"requested version. Run the export with the {requested} CLI, or request {packageName}@{ExecutionContext.IdentitySdkVersion}."; + } + private async Task ExportApiAsync( string language, string packageName, @@ -214,6 +258,8 @@ private async Task ExportApiAsync( ? packageVersion : ExecutionContext.IdentityVersion; + string? rejection = null; + await using var session = await SdkCommandPreparation.PrepareSessionAsync( _appHostServerProjectFactory, _serverSessionFactory, @@ -223,11 +269,16 @@ private async Task ExportApiAsync( sdkVersion, integrations, packageSource, + validateProject: serverProject => rejection = ValidateRequestedPackageIsRestorable(serverProject, packageName, packageVersion), cancellationToken); if (session is null) { - return CliExitCodes.FailedToBuildArtifacts; + // A rejection is a usage error the caller fixes by asking for a different version or + // running a different CLI, so it must not look like the scanner failed to build. + return rejection is not null + ? CliExitCodes.InvalidCommand + : CliExitCodes.FailedToBuildArtifacts; } JsonElement export; diff --git a/src/Aspire.Cli/Configuration/IntegrationReference.cs b/src/Aspire.Cli/Configuration/IntegrationReference.cs index 79cbe97b65a..6f2e458db1f 100644 --- a/src/Aspire.Cli/Configuration/IntegrationReference.cs +++ b/src/Aspire.Cli/Configuration/IntegrationReference.cs @@ -34,6 +34,21 @@ internal sealed class IntegrationReference /// public bool IsPackageReference => Version is not null; + /// + /// Gets a value indicating whether must resolve to exactly that version. + /// + /// + /// A bare NuGet version is a minimum, not an equality: 13.5.0 means + /// [13.5.0, ) and resolves to the nearest version at or above it, so a version that is + /// missing from the feed silently restores as a later one. Only [13.5.0] pins a single + /// version. Callers that publish artifacts keyed on the requested version — aspire sdk + /// export — set this so an unavailable version fails the restore instead of being described + /// under the wrong number. Everything else keeps the minimum form, which is what lets a shared + /// transitive dependency unify. + /// See https://learn.microsoft.com/nuget/concepts/package-versioning#version-ranges. + /// + public bool RequireExactVersion { get; init; } + /// /// Creates a NuGet package reference. /// @@ -47,6 +62,46 @@ public static IntegrationReference FromPackage(string name, string version) return new IntegrationReference { Name = name, Version = version }; } + /// + /// Creates a NuGet package reference that must restore at exactly . + /// + /// The package name. + /// The NuGet package version. + /// + public static IntegrationReference FromExactPackage(string name, string version) + { + ArgumentException.ThrowIfNullOrEmpty(name); + ArgumentException.ThrowIfNullOrEmpty(version); + + return new IntegrationReference { Name = name, Version = version, RequireExactVersion = true }; + } + + /// + /// Gets the NuGet version range to restore this reference with. + /// + /// + /// Pins the version even when is not set, for callers that + /// decide exactness from context rather than from the reference (for example, restoring Aspire + /// packages from an explicit --source). + /// + /// Either the version as written, or [version] when it has to be pinned. + public string GetRestoreVersionRange(bool forceExact) + { + if (Version is null) + { + throw new InvalidOperationException($"Integration '{Name}' is a project reference and has no version to restore."); + } + + // An explicit range the caller already wrote (`[1.2.3]`, `(1.0,2.0)`) is left alone: wrapping + // it again would produce a syntactically invalid range. + if (!(forceExact || RequireExactVersion) || Version.Length == 0 || Version[0] is '[' or '(') + { + return Version; + } + + return $"[{Version}]"; + } + /// /// Creates a local project reference. /// diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index 2413850ecde..1a30bf9afc7 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -167,7 +167,7 @@ private XDocument CreateProjectFile(IEnumerable integratio // Add project references for Aspire.Hosting.* packages, NuGet for others var projectRefGroup = new XElement("ItemGroup"); var addedProjects = new HashSet(StringComparer.OrdinalIgnoreCase); - var otherPackages = new List<(string Name, string Version)>(); + var otherPackages = new List(); foreach (var integration in integrations) { @@ -183,8 +183,8 @@ private XDocument CreateProjectFile(IEnumerable integratio } else if (integration.Name.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase)) { - var projectPath = Path.Combine(_repoRoot, "src", integration.Name, $"{integration.Name}.csproj"); - if (File.Exists(projectPath) && addedProjects.Add(integration.Name)) + var projectPath = GetLocalProjectSubstitution(integration.Name); + if (projectPath is not null && addedProjects.Add(integration.Name)) { projectRefGroup.Add(new XElement("ProjectReference", new XAttribute("Include", projectPath), @@ -197,7 +197,7 @@ private XDocument CreateProjectFile(IEnumerable integratio { throw new InvalidOperationException($"Integration '{integration.Name}' is neither a project reference nor a package reference (both Version and ProjectPath are null)."); } - otherPackages.Add((integration.Name, integration.Version)); + otherPackages.Add(integration); } } @@ -224,7 +224,7 @@ private XDocument CreateProjectFile(IEnumerable integratio doc.Root!.Add(new XElement("ItemGroup", otherPackages.Select(p => new XElement("PackageReference", new XAttribute("Include", p.Name), - new XAttribute("VersionOverride", p.Version))))); + new XAttribute("VersionOverride", p.GetRestoreVersionRange(forceExact: false)))))); } // Add imports for in-repo AppHost building @@ -473,6 +473,24 @@ public async Task PrepareAsync( /// public string GetInstanceIdentifier() => GetProjectFilePath(); + /// + /// + /// This is the same decision makes, kept in one place so a + /// caller asking "will my requested version survive?" cannot drift from what the generated + /// project actually does. Only first-party Aspire.Hosting.* packages live under + /// src/, so a third-party integration is always restored from a feed even here. + /// + public string? GetLocalProjectSubstitution(string packageName) + { + if (!packageName.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + var projectPath = Path.Combine(_repoRoot, "src", packageName, $"{packageName}.csproj"); + return File.Exists(projectPath) ? projectPath : null; + } + /// public async Task RunAsync( int hostPid, diff --git a/src/Aspire.Cli/Projects/IAppHostServerProject.cs b/src/Aspire.Cli/Projects/IAppHostServerProject.cs index baf287db6eb..8aa92ed910c 100644 --- a/src/Aspire.Cli/Projects/IAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/IAppHostServerProject.cs @@ -136,4 +136,17 @@ Task RunAsync( /// /// A path that uniquely identifies this AppHost. string GetInstanceIdentifier(); + + /// + /// Gets the local project this server builds in place of , or + /// when the package is restored from a feed at the requested version. + /// + /// + /// Only the repository development server substitutes projects for packages, so every other + /// implementation keeps this default. Callers that publish artifacts keyed on a package version + /// need to know the difference: a substituted project carries the checkout's API surface rather + /// than the surface of the version that was asked for. + /// + /// The package name the caller asked to restore. + string? GetLocalProjectSubstitution(string packageName) => null; } diff --git a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs index 5c8799ead3a..3e7078ae7e9 100644 --- a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs +++ b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs @@ -298,7 +298,7 @@ private async Task RestoreNuGetPackagesAsync( var useExactPackageVersions = !string.IsNullOrWhiteSpace(packageSourceOverride); var packages = packageRefs - .Select(r => (r.Name, Version: GetRestoreVersion(r.Name, r.Version!, useExactPackageVersions))) + .Select(r => (r.Name, Version: GetRestoreVersion(r, useExactPackageVersions))) .ToList(); using var temporaryNuGetConfig = await TryCreateTemporaryNuGetConfigAsync(requestedChannel, packageSourceOverride, cancellationToken); var sources = await GetNuGetSourcesAsync(requestedChannel, packageSourceOverride, cancellationToken); @@ -490,7 +490,7 @@ internal static string GenerateIntegrationProjectFile( } return new XElement("PackageReference", new XAttribute("Include", p.Name), - new XAttribute("Version", GetRestoreVersion(p.Name, p.Version, useExactPackageVersions))); + new XAttribute("Version", GetRestoreVersion(p, useExactPackageVersions))); }))); } @@ -903,15 +903,15 @@ private async Task> GetExplicitRestoreChannelsAsync( return channels.Where(c => c.Type == PackageChannelType.Explicit).ToArray(); } - private static string GetRestoreVersion(string packageName, string version, bool useExactPackageVersions) + private static string GetRestoreVersion(IntegrationReference reference, bool useExactPackageVersions) { - var shouldUseExactAspirePackageVersion = useExactPackageVersions && packageName.StartsWith("Aspire", StringComparison.OrdinalIgnoreCase); - if (!shouldUseExactAspirePackageVersion || version.Length == 0 || version[0] is '[' or '(') - { - return version; - } + // The `--source` case pins Aspire packages so a private hive cannot be topped up from a + // public feed. A reference that already demands exactness pins regardless of package name, + // which is what lets `sdk export` restore a third-party integration at exactly one version. + var shouldUseExactAspirePackageVersion = useExactPackageVersions + && reference.Name.StartsWith("Aspire", StringComparison.OrdinalIgnoreCase); - return $"[{version}]"; + return reference.GetRestoreVersionRange(forceExact: shouldUseExactAspirePackageVersion); } // Display-safe form of a NuGet source used in user-visible error footers. Delegates to the diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index 7bcea10da92..60e078c5352 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -278,7 +278,10 @@ public Dictionary GenerateCode(string language, string? assembly /// /// The target language (e.g., "TypeScript"). /// The package to export documentation for. - /// The exact resolved version of . + /// + /// The version label to record for . The caller owns its accuracy; + /// see . + /// /// The language provider's API reference document, verbatim. [JsonRpcMethod(ExportApiMethodName)] public JsonElement ExportApi(string language, string packageName, string packageVersion) diff --git a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs index 20138f444ae..ddbcbec9432 100644 --- a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs +++ b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs @@ -19,11 +19,19 @@ public sealed class ApiReferenceExportOptions /// Initializes a new instance of the class. /// /// The name of the package being exported. - /// The exact version of the package being exported. + /// The version label to record for the package being exported. /// /// The assemblies whose symbols this package owns and documents. Symbols outside this set are /// present only to complete the reference closure. /// + /// + /// Thrown when , , or + /// is . + /// + /// + /// Thrown when or is empty or + /// consists only of white-space characters. + /// public ApiReferenceExportOptions( string packageName, string packageVersion, @@ -44,9 +52,18 @@ public ApiReferenceExportOptions( public string PackageName { get; } /// - /// Gets the exact version of the package being exported. Consumers key published documentation on - /// this value, so it must be a resolved version and never a floating range. + /// Gets the version label recorded for this export, as supplied by the caller. /// + /// + /// Consumers key published documentation on this value, so callers are expected to pass the + /// exact version that was restored. Nothing on this type can confirm that: an exporter sees + /// loaded assemblies, not the package resolution that produced them, so any value — including a + /// floating or range expression — would be recorded verbatim. Exactness therefore belongs where + /// the restore is decided. aspire sdk export rejects a floating or range version before + /// the scanner is built, pins the requested version so an unavailable one fails the restore + /// instead of resolving upward, and refuses a package a repository checkout would build in place + /// of the requested one. + /// public string PackageVersion { get; } /// diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 39e53ad2d2a..354c01f0779 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -199,6 +199,96 @@ public async Task SdkExportWithFloatingVersionReturnsInvalidCommand(string versi Assert.Empty(interactionService.DisplayedRawText); } + [Fact] + public async Task SdkExportForAPackageTheCheckoutWouldSubstituteReturnsInvalidCommand() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + appHostServerProject.LocalProjectSubstitutions["Aspire.Hosting.Redis"] = + Path.Combine("src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + + // A CLI running from a repository checkout builds first-party integrations from src/ and + // throws the requested package version away, so honouring this would publish the checkout's + // API surface under 13.5.0 — the mislabel this command exists to prevent. + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + + [Fact] + public async Task SdkExportForASubstitutedPackageAtTheCheckoutVersionSucceeds() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + appHostServerProject.LocalProjectSubstitutions["Aspire.Hosting.Redis"] = + Path.Combine("src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + + // Exporting the version the checkout actually contains is the local development case and + // stays supported: the project reference and the label describe the same surface. + var checkoutVersion = provider.GetRequiredService().IdentitySdkVersion; + + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{checkoutVersion}"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("typescript", "Aspire.Hosting.Redis", checkoutVersion), rpcClient.LastExportRequest); + } + + [Fact] + public async Task SdkExportForAThirdPartyPackageIsUnaffectedByCheckoutSubstitution() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + appHostServerProject.LocalProjectSubstitutions["Aspire.Hosting.Redis"] = + Path.Combine("src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + + // A Community Toolkit integration is never replaced by a repository project, so it restores + // at the requested version even from a checkout and must keep exporting. + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package CommunityToolkit.Aspire.Hosting.ActiveMQ@13.4.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("typescript", "CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0"), rpcClient.LastExportRequest); + } + + /// + /// A bare NuGet version is a minimum, not an equality, so a package that is missing from the feed + /// restores as the next one up and the export is published under a version it does not describe. + /// Only the requested package is pinned; the code generation package tracks this CLI and is + /// resolved the same way sdk generate resolves it. + /// + [Fact] + public async Task SdkExportPinsOnlyTheRequestedPackageToAnExactVersion() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); + using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + + var requested = Assert.Single(appHostServerProject.Integrations, integration => integration.Name == "Aspire.Hosting.Redis"); + Assert.True(requested.RequireExactVersion); + + var codeGeneration = Assert.Single( + appHostServerProject.Integrations, + integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); + Assert.False(codeGeneration.RequireExactVersion); + } + [Fact] public async Task SdkExportWithUnsupportedLanguageReturnsInvalidCommand() { diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs index ce174c8538d..f33538b3b7c 100644 --- a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs @@ -30,16 +30,7 @@ public async Task CreateProjectFiles_PinsOutOfRepoIntegrationsWithVersionOverrid var appPath = workspace.WorkspaceRoot.FullName; var projectModelPath = Path.Combine(appPath, ".aspire_server"); - var project = new DotNetBasedAppHostServerProject( - appPath, - socketPath: "test.sock", - repoRoot: appPath, - new TestDotNetCliRunner(), - MockPackagingServiceFactory.Create(), - new TestProcessExecutionFactory(), - new TestEnvironment(), - NullLogger.Instance, - projectModelPath); + var project = CreateProject(appPath, projectModelPath); // There is no src/CommunityToolkit.Aspire.Hosting.ActiveMQ under the fake repo root, so this // integration takes the package path rather than the project-reference path. @@ -93,16 +84,7 @@ await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), """); - var project = new DotNetBasedAppHostServerProject( - appPath, - socketPath: "test.sock", - repoRoot: appPath, - new TestDotNetCliRunner(), - MockPackagingServiceFactory.Create(), - new TestProcessExecutionFactory(), - new TestEnvironment(), - NullLogger.Instance, - projectModelPath); + var project = CreateProject(appPath, projectModelPath); await project.CreateProjectFilesAsync( [IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")]); @@ -120,6 +102,135 @@ await project.CreateProjectFilesAsync( Assert.Equal(0, exitCode); } + /// + /// aspire sdk export publishes documentation keyed on the requested version, so the + /// restore has to fail when that version is unavailable rather than resolve to a later one. + /// + [Fact] + public async Task CreateProjectFiles_PinsExactIntegrationsToASingleVersionRange() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + var projectModelPath = Path.Combine(appPath, ".aspire_server"); + + var project = CreateProject(appPath, projectModelPath); + + await project.CreateProjectFilesAsync( + [ + IntegrationReference.FromExactPackage("CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0"), + IntegrationReference.FromPackage("CommunityToolkit.Aspire.Hosting.Dapr", "13.4.0") + ]); + + var references = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")) + .Descendants("PackageReference") + .ToDictionary(element => element.Attribute("Include")!.Value, element => element.Attribute("VersionOverride")?.Value); + + Assert.Equal("[13.4.0]", references["CommunityToolkit.Aspire.Hosting.ActiveMQ"]); + + // Everything else keeps the minimum-version form the run and dump paths have always used. + Assert.Equal("13.4.0", references["CommunityToolkit.Aspire.Hosting.Dapr"]); + } + + /// + /// The generated scanner replaces a first-party Aspire.Hosting.* package reference with the + /// matching repository project and drops the requested version, so a caller that publishes + /// artifacts keyed on that version has to be able to see the substitution coming. + /// + [Fact] + public void GetLocalProjectSubstitution_ReportsOnlyFirstPartyProjectsThatExist() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + + var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); + File.WriteAllText(redisProjectPath, ""); + + var project = CreateProject(appPath, Path.Combine(appPath, ".aspire_server")); + + Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("Aspire.Hosting.Redis")); + + // No src/Aspire.Hosting.Qdrant in this checkout, so the package really is restored. + Assert.Null(project.GetLocalProjectSubstitution("Aspire.Hosting.Qdrant")); + + // Third-party integrations are never substituted, even when a same-named folder exists. + Assert.Null(project.GetLocalProjectSubstitution("CommunityToolkit.Aspire.Hosting.ActiveMQ")); + } + + /// + /// The generated XML cannot show what NuGet does with it. This restores twice against an offline + /// feed that holds 13.4.1 but not the requested 13.4.0: the plain reference silently resolves + /// upward (which is what mislabels an export), and the exact reference fails instead. + /// + [Fact] + public async Task CreateProjectFiles_ExactIntegrationDoesNotFloatToALaterPackage() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + var feedPath = Path.Combine(appPath, "feed"); + Directory.CreateDirectory(feedPath); + + const string IntegrationPackage = "Contoso.Aspire.Hosting.ExactVersionProbe"; + + CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); + CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); + CreateStubPackage(feedPath, IntegrationPackage, "13.4.1"); + + await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), """ + + + + + + + """); + + var floatingModelPath = Path.Combine(appPath, ".aspire_server_floating"); + await CreateProject(appPath, floatingModelPath) + .CreateProjectFilesAsync([IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")]); + + var (floatingExitCode, floatingOutput) = await RestoreAsync( + Path.Combine(floatingModelPath, "AppHostServer.csproj"), + feedPath); + outputHelper.WriteLine(floatingOutput); + + // 13.4.0 is a minimum, so NuGet happily hands back 13.4.1 and warns rather than fails. The + // assets file records what was actually resolved, which the console output does not always + // spell out. + Assert.Equal(0, floatingExitCode); + Assert.Contains("NU1603", floatingOutput, StringComparison.Ordinal); + Assert.Contains( + $"{IntegrationPackage}/13.4.1", + await File.ReadAllTextAsync(Path.Combine(floatingModelPath, "obj", "project.assets.json")), + StringComparison.Ordinal); + + var exactModelPath = Path.Combine(appPath, ".aspire_server_exact"); + await CreateProject(appPath, exactModelPath) + .CreateProjectFilesAsync([IntegrationReference.FromExactPackage(IntegrationPackage, "13.4.0")]); + + var (exactExitCode, exactOutput) = await RestoreAsync( + Path.Combine(exactModelPath, "AppHostServer.csproj"), + feedPath); + outputHelper.WriteLine(exactOutput); + + // NU1102 is "package found but not at the requested version", which is the failure a caller + // needs instead of a document labelled 13.4.0 that describes 13.4.1. + Assert.NotEqual(0, exactExitCode); + Assert.Contains("NU1102", exactOutput, StringComparison.Ordinal); + } + + private static DotNetBasedAppHostServerProject CreateProject(string appPath, string projectModelPath) + => new( + appPath, + socketPath: "test.sock", + repoRoot: appPath, + new TestDotNetCliRunner(), + MockPackagingServiceFactory.Create(), + new TestProcessExecutionFactory(), + new TestEnvironment(), + NullLogger.Instance, + projectModelPath); + private static void CreateStubPackage(string feedPath, string id, string version) { var stagingPath = Path.Combine(feedPath, $".staging-{id}"); diff --git a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs index 898530cbad5..adbb03eb890 100644 --- a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs @@ -44,6 +44,27 @@ public void GenerateIntegrationProjectFile_WithPackagesOnly_ProducesPackageRefer Assert.Empty(doc.Descendants("ProjectReference")); } + [Fact] + public void GenerateIntegrationProjectFile_PinsExactPackagesToASingleVersionRange() + { + var packageRefs = new List + { + IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", "13.2.0"), + IntegrationReference.FromPackage("Aspire.Hosting", "13.2.0") + }; + + var xml = PrebuiltAppHostServer.GenerateIntegrationProjectFile(packageRefs, [], "/tmp/libs"); + var doc = XDocument.Parse(xml); + + var versions = doc.Descendants("PackageReference") + .ToDictionary(e => e.Attribute("Include")!.Value, e => e.Attribute("Version")!.Value); + + // `13.2.0` is a NuGet minimum, so only the bracketed form keeps an unavailable version from + // resolving upward and being documented under the requested number. + Assert.Equal("[13.2.0]", versions["Aspire.Hosting.Redis"]); + Assert.Equal("13.2.0", versions["Aspire.Hosting"]); + } + [Fact] public void GenerateIntegrationProjectFile_WithProjectRefsOnly_ProducesProjectReferences() { diff --git a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs index 8e6defbdabe..9e7c8ff762e 100644 --- a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs +++ b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs @@ -16,8 +16,19 @@ internal sealed class FakeSucceedingAppHostServerProject(string appDirectoryPath { public string AppDirectoryPath { get; } = appDirectoryPath; + /// + /// Package names this fake reports as satisfied by a repository project, keyed to the project + /// path. Mirrors in repository dev mode, where an + /// Aspire.Hosting.* package reference is replaced by the matching project under + /// src/ and the requested package version is discarded. + /// + public Dictionary LocalProjectSubstitutions { get; } = new(StringComparer.OrdinalIgnoreCase); + public string GetInstanceIdentifier() => AppDirectoryPath; + public string? GetLocalProjectSubstitution(string packageName) + => LocalProjectSubstitutions.TryGetValue(packageName, out var projectPath) ? projectPath : null; + public Task PrepareAsync( string sdkVersion, IEnumerable integrations, From 459d81c2dd396b1b7b36c87d14833b13b22d8f5c Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 07:14:34 -0400 Subject: [PATCH 17/73] Verify sdk export provenance instead of trusting a name or an override Three holes remained in the exact-version work. A first-party name did not mean the checkout could supply it. The repository scanner substituted `src//.csproj` for every `Aspire.Hosting*` reference and, when that project was absent, dropped the reference outright, so `sdk export --package Aspire.Hosting.DoesNotExist@13.5.0-dev` restored cleanly and published an empty module under a package id that has never existed. It now falls back to an exact package reference, which fails with NU1101 as it should. The skew check compared the request against `IdentitySdkVersion`, which `ASPIRE_CLI_VERSION` and the install sidecar exist to override, so `ASPIRE_CLI_VERSION=99.0.0` published the current Redis source as 99.0.0. The checkout now states its own version line from eng/Versions.props, and an identity override, an unreadable version line, or a mismatch on either half rejects. Overrides keep working everywhere no substitution happens, which is every prebuilt and non-first-party path. The restore-failure footer printed the raw version where restore was given a range, sending a reader looking for a resolution failure that `[13.4.0]` explains on sight. `sdk dump` keeps requested-version semantics deliberately: it restores with a minimum-version reference, and `--format ci` -- the format the checked-in *.ats.txt baselines use -- carries no package versions at all, so nothing version-keyed is published from it. That distinction is now stated in code, in the output-format spec, and in a test rather than left to be rediscovered. Also covers the prebuilt bundled restore pin and the pre-bracketed range invariant, and moves the offline-feed test helpers to a shared class. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ffeff87e-f284-434d-87d3-843e21a7aebb --- docs/specs/cli-output-formats.md | 2 +- src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs | 12 ++ .../Commands/Sdk/SdkExportCommand.cs | 51 ++++++- .../DotNetBasedAppHostServerProject.cs | 95 +++++++++++- .../Projects/IAppHostServerProject.cs | 2 +- .../Projects/LocalProjectSubstitution.cs | 23 +++ .../Projects/PrebuiltAppHostServer.cs | 5 +- .../Commands/Sdk/SdkExportCommandTests.cs | 112 +++++++++++++- .../Commands/SdkDumpCommandTests.cs | 64 ++++++++ .../IntegrationReferenceTests.cs | 37 +++++ ...BasedAppHostServerPackageReferenceTests.cs | 143 ++++++++++-------- .../Projects/PrebuiltAppHostServerTests.cs | 131 +++++++++++++++- .../FakeSucceedingAppHostServerProject.cs | 19 ++- .../Utils/OfflineNuGetFeed.cs | 87 +++++++++++ 14 files changed, 680 insertions(+), 103 deletions(-) create mode 100644 src/Aspire.Cli/Projects/LocalProjectSubstitution.cs create mode 100644 tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs diff --git a/docs/specs/cli-output-formats.md b/docs/specs/cli-output-formats.md index 350f22e00e8..bfa2ae3050f 100644 --- a/docs/specs/cli-output-formats.md +++ b/docs/specs/cli-output-formats.md @@ -573,7 +573,7 @@ The top-level arrays are: | Field | Description | | ----- | ----------- | -| `packages` | Packages or projects scanned for capabilities. | +| `packages` | Packages or projects scanned for capabilities. `version` is the version that was **requested**, not the one NuGet resolved: package restore uses a minimum-version reference, so the assembly actually scanned may be newer. Use `aspire sdk export` when the version label has to be exact. Project references are omitted because they have no version. | | `capabilities` | Builder methods and other callable capabilities. | | `handleTypes` | Resource or builder handle types. | | `dtoTypes` | DTO types used by capabilities. | diff --git a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs index b94689a6a5c..3a5d3446b22 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs @@ -285,10 +285,18 @@ private void PrepareCapabilitiesForOutput(CapabilitiesInfo capabilities, IEnumer capabilities.Diagnostics.RemoveAll(d => d.Severity == "Info"); + // This records what the caller asked to scan, not what NuGet resolved. `sdk dump` restores + // with a minimum-version reference (see IntegrationReference.GetRestoreVersionRange) and, in + // a repository checkout, may build a first-party integration from src/ instead, so a scan of + // 13.4.0 can legitimately report on 13.4.1. That is intentional: dump is an inspection tool, + // and `--format ci` — the format the checked-in *.ats.txt baselines use — carries no package + // versions at all, so nothing version-keyed is published from this block. `sdk export` is the + // command that has to make the label true, and it pins the restore and rejects checkout skew. var packageVersions = integrations .Where(i => i.IsPackageReference) .Select(i => new PackageInfo { Name = i.Name, Version = i.Version! }) .ToList(); + if (packageVersions.Count > 0) { capabilities.Packages = packageVersions; @@ -634,6 +642,10 @@ internal sealed class CapabilitiesInfo internal sealed class PackageInfo { public string Name { get; set; } = ""; + + // The version that was requested on the command line, not the one NuGet resolved. Restore uses a + // minimum-version reference, so the scanned assembly can be newer; see the comment in + // SdkDumpCommand.PrepareCapabilitiesForOutput for why dump keeps requested-version semantics. public string Version { get; set; } = ""; } diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 9ac0511e8d6..900d9baf335 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -7,6 +7,7 @@ using Aspire.Cli.Interaction; using Aspire.Cli.Projects; using Microsoft.Extensions.Logging; +using Semver; using StreamJsonRpc; namespace Aspire.Cli.Commands.Sdk; @@ -206,14 +207,23 @@ private static string StripBuildMetadata(string version) /// requested package version. /// /// + /// /// In repository development mode the scanner AppHost replaces every first-party - /// Aspire.Hosting.* package reference with the matching project under src/ and + /// Aspire.Hosting.* package reference that exists under src/ with that project and /// discards the requested version, so the checkout's API surface would be published under /// someone else's version number. That is the same stale-signature problem the core-package /// guard prevents, so this refuses for the same reason. Asking for the version this CLI was /// built from is still allowed: that is exactly what the checkout contains. The core package is /// already handled before any project is created, and third-party packages are never /// substituted, so both fall straight through. + /// + /// + /// The check cannot rest on alone, because + /// that value is overrideable by design (ASPIRE_CLI_VERSION, the install sidecar) and + /// would let a caller name local source whatever they like. The checkout's own version line is + /// the independent half; the identity is still compared so a checkout on the right line cannot + /// publish a neighbouring build's number. + /// /// /// The scanner AppHost that will restore the export. /// The package being exported. @@ -226,21 +236,46 @@ private static string StripBuildMetadata(string version) return null; } - if (serverProject.GetLocalProjectSubstitution(packageName) is not string localProjectPath) + if (serverProject.GetLocalProjectSubstitution(packageName) is not { } substitution) { return null; } + var preamble = $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {substitution.ProjectPath} " + + $"instead of being restored from a package feed."; + + if (ExecutionContext.IdentityOverridden) + { + // An ASPIRE_CLI_* override makes this run an emulation of a build the checkout is not, + // which is exactly the combination that cannot be checked: both the source and the label + // are caller-controlled. The overrides stay available for every non-substituted path. + return $"{preamble} This run also has an ASPIRE_CLI_* identity override in effect, so nothing can confirm the " + + $"checkout really is {packageVersion}. Re-run without the override, or export {packageName} from an installed CLI."; + } + + if (substitution.CheckoutVersionPrefix is not string checkoutPrefix) + { + return $"{preamble} This checkout does not say which version it builds (eng/Versions.props is missing or unreadable), " + + $"so an export labelled {packageVersion} cannot be verified. Export {packageName} from an installed CLI instead."; + } + + if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out var requestedVersion) + || $"{requestedVersion.Major}.{requestedVersion.Minor}.{requestedVersion.Patch}" != checkoutPrefix) + { + return $"{preamble} That checkout builds {checkoutPrefix}, but {packageVersion} was requested, and exporting it " + + $"would describe the checkout's API surface under the requested version. " + + $"Run the export with the {StripBuildMetadata(packageVersion)} CLI instead."; + } + var requested = StripBuildMetadata(packageVersion); - if (string.Equals(requested, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(requested, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) { - return null; + return $"{preamble} That checkout is {ExecutionContext.IdentitySdkVersion}, but {packageVersion} was requested, " + + $"and exporting it would describe the checkout's API surface under the requested version. " + + $"Run the export with the {requested} CLI, or request {packageName}@{ExecutionContext.IdentitySdkVersion}."; } - return $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {localProjectPath} " + - $"instead of being restored from a package feed. That checkout is {ExecutionContext.IdentitySdkVersion}, " + - $"but {packageVersion} was requested, and exporting it would describe the checkout's API surface under the " + - $"requested version. Run the export with the {requested} CLI, or request {packageName}@{ExecutionContext.IdentitySdkVersion}."; + return null; } private async Task ExportApiAsync( diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index 1a30bf9afc7..0cb3eaf1663 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; @@ -43,6 +44,10 @@ internal sealed class DotNetBasedAppHostServerProject : IAppHostServerProject private readonly ILogger _logger; private readonly string? _logFilePath; + // Boxed so "not read yet" and "read, and there is no answer" stay distinguishable without + // re-parsing eng/Versions.props on every lookup. + private StrongBox? _repositoryVersionPrefix; + public DotNetBasedAppHostServerProject( string appPath, string socketPath, @@ -183,12 +188,25 @@ private XDocument CreateProjectFile(IEnumerable integratio } else if (integration.Name.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase)) { - var projectPath = GetLocalProjectSubstitution(integration.Name); - if (projectPath is not null && addedProjects.Add(integration.Name)) + if (GetLocalProjectSubstitution(integration.Name) is { } substitution) { - projectRefGroup.Add(new XElement("ProjectReference", - new XAttribute("Include", projectPath), - new XElement("IsAspireProjectResource", "false"))); + if (addedProjects.Add(integration.Name)) + { + projectRefGroup.Add(new XElement("ProjectReference", + new XAttribute("Include", substitution.ProjectPath), + new XElement("IsAspireProjectResource", "false"))); + } + } + else + { + // A first-party name does not mean this checkout can supply it. Dropping the + // reference here used to make a nonexistent package scan clean and export an + // empty module, so fall back to restoring it like any other package. + if (integration.Version is null) + { + throw new InvalidOperationException($"Integration '{integration.Name}' is neither a project reference nor a package reference (both Version and ProjectPath are null)."); + } + otherPackages.Add(integration); } } else @@ -480,7 +498,7 @@ public async Task PrepareAsync( /// project actually does. Only first-party Aspire.Hosting.* packages live under /// src/, so a third-party integration is always restored from a feed even here. /// - public string? GetLocalProjectSubstitution(string packageName) + public LocalProjectSubstitution? GetLocalProjectSubstitution(string packageName) { if (!packageName.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase)) { @@ -488,7 +506,70 @@ public async Task PrepareAsync( } var projectPath = Path.Combine(_repoRoot, "src", packageName, $"{packageName}.csproj"); - return File.Exists(projectPath) ? projectPath : null; + return File.Exists(projectPath) + ? new LocalProjectSubstitution(projectPath, GetRepositoryVersionPrefix()) + : null; + } + + /// + /// Reads the Major.Minor.Patch this checkout builds from eng/Versions.props, or + /// when it cannot be established. + /// + /// + /// + /// The repository states its version line as three properties that VersionPrefix is + /// composed from: + /// + /// <MajorVersion>13</MajorVersion> + /// <MinorVersion>5</MinorVersion> + /// <PatchVersion>0</PatchVersion> + /// <VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix> + /// + /// VersionPrefix itself is read as the unexpanded MSBuild expression, so the three parts + /// are read directly. The prerelease suffix (-preview.1.25366.3) is assigned by Arcade at + /// build time and is not in the checkout, which is why only the prefix can be established here. + /// + /// + /// Any failure returns rather than throwing: this only informs callers + /// that need provenance, and no other caller should lose a scanner over an unreadable file. + /// + /// + private string? GetRepositoryVersionPrefix() + { + if (_repositoryVersionPrefix is { } cached) + { + return cached.Value; + } + + _repositoryVersionPrefix = ReadRepositoryVersionPrefix(_repoRoot); + return _repositoryVersionPrefix.Value; + } + + private static StrongBox ReadRepositoryVersionPrefix(string repoRoot) + { + try + { + var versionsPropsPath = Path.Combine(repoRoot, "eng", "Versions.props"); + if (!File.Exists(versionsPropsPath)) + { + return new StrongBox(null); + } + + var doc = XDocument.Load(versionsPropsPath); + + var major = doc.Descendants("MajorVersion").FirstOrDefault()?.Value; + var minor = doc.Descendants("MinorVersion").FirstOrDefault()?.Value; + var patch = doc.Descendants("PatchVersion").FirstOrDefault()?.Value; + + return new StrongBox( + string.IsNullOrWhiteSpace(major) || string.IsNullOrWhiteSpace(minor) || string.IsNullOrWhiteSpace(patch) + ? null + : $"{major.Trim()}.{minor.Trim()}.{patch.Trim()}"); + } + catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or System.Xml.XmlException) + { + return new StrongBox(null); + } } /// diff --git a/src/Aspire.Cli/Projects/IAppHostServerProject.cs b/src/Aspire.Cli/Projects/IAppHostServerProject.cs index 8aa92ed910c..4fbcb761233 100644 --- a/src/Aspire.Cli/Projects/IAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/IAppHostServerProject.cs @@ -148,5 +148,5 @@ Task RunAsync( /// than the surface of the version that was asked for. /// /// The package name the caller asked to restore. - string? GetLocalProjectSubstitution(string packageName) => null; + LocalProjectSubstitution? GetLocalProjectSubstitution(string packageName) => null; } diff --git a/src/Aspire.Cli/Projects/LocalProjectSubstitution.cs b/src/Aspire.Cli/Projects/LocalProjectSubstitution.cs new file mode 100644 index 00000000000..a67da58f626 --- /dev/null +++ b/src/Aspire.Cli/Projects/LocalProjectSubstitution.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.Cli.Projects; + +/// +/// A package an AppHost server builds from local source instead of restoring from a feed. +/// +/// +/// This only happens in repository development mode. It matters to callers that publish artifacts +/// keyed on a package version, because the substituted project carries whatever the checkout +/// currently contains rather than the version that was requested. +/// +/// The project built in place of the package. +/// +/// The Major.Minor.Patch the checkout produces, read from the checkout itself, or +/// when it cannot be established. This is deliberately not the running CLI's +/// reported version: that value is overrideable (ASPIRE_CLI_VERSION, the install sidecar), so +/// checking a requested version against it alone lets a caller name local source whatever they like. +/// It is a prefix rather than a full version because the prerelease suffix is assigned at build time +/// by Arcade and is not recorded in the checkout. +/// +internal sealed record LocalProjectSubstitution(string ProjectPath, string? CheckoutVersionPrefix); diff --git a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs index 3e7078ae7e9..661a83a8896 100644 --- a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs +++ b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs @@ -280,7 +280,10 @@ private static void AppendRestoreContextOnFailure( if (packageRefs.Count > 0) { - var preview = packageRefs.Take(5).Select(static r => $"{r.Name} {r.Version}"); + // Show the range restore was actually given, not the raw version: `--source` and + // exact references both pin to `[x.y.z]`, and a reader chasing a resolution failure + // needs to see that the request was an equality rather than a minimum. + var preview = packageRefs.Take(5).Select(r => $"{r.Name} {GetRestoreVersion(r, hasOverride)}"); output.AppendError($" packages: {string.Join(", ", preview)}{(packageRefs.Count > 5 ? $", … (+{packageRefs.Count - 5} more)" : string.Empty)}"); } } diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 354c01f0779..c10192042c7 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -11,6 +11,7 @@ using Aspire.Cli.Commands.Sdk; using Microsoft.AspNetCore.InternalTesting; using Microsoft.Extensions.DependencyInjection; +using Semver; using StreamJsonRpc; namespace Aspire.Cli.Tests.Commands.Sdk; @@ -205,10 +206,9 @@ public async Task SdkExportForAPackageTheCheckoutWouldSubstituteReturnsInvalidCo var interactionService = new TestInteractionService(); using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - appHostServerProject.LocalProjectSubstitutions["Aspire.Hosting.Redis"] = - Path.Combine("src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); var rpcClient = new StubExportRpcClient(); using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", CheckoutVersionPrefix(provider)); // A CLI running from a repository checkout builds first-party integrations from src/ and // throws the requested package version away, so honouring this would publish the checkout's @@ -226,10 +226,9 @@ public async Task SdkExportForASubstitutedPackageAtTheCheckoutVersionSucceeds() var interactionService = new TestInteractionService(); using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - appHostServerProject.LocalProjectSubstitutions["Aspire.Hosting.Redis"] = - Path.Combine("src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); var rpcClient = new StubExportRpcClient(); using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", CheckoutVersionPrefix(provider)); // Exporting the version the checkout actually contains is the local development case and // stays supported: the project reference and the label describe the same surface. @@ -241,16 +240,93 @@ public async Task SdkExportForASubstitutedPackageAtTheCheckoutVersionSucceeds() Assert.Equal(("typescript", "Aspire.Hosting.Redis", checkoutVersion), rpcClient.LastExportRequest); } + /// + /// The version this CLI reports is overrideable (ASPIRE_CLI_VERSION, the install sidecar), + /// so comparing the request against it alone lets a caller name the checkout whatever they like. + /// The version the checkout actually builds comes from the checkout itself and settles it. + /// + [Fact] + public async Task SdkExportRejectsASubstitutedPackageWhenTheCheckoutBuildsADifferentVersion() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "99.0.0"); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", "13.5.0"); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@99.0.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + + /// + /// An ASPIRE_CLI_* override makes the run an emulation of a build this checkout is not. + /// The overrides stay useful everywhere else; they just cannot also decide the label on a + /// document generated from local source. + /// + [Fact] + public async Task SdkExportRejectsASubstitutedPackageWhenTheCliIdentityIsOverridden() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.5.0", + identityOverridden: true); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", "13.5.0"); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + + /// + /// When the checkout cannot say what it builds there is nothing left to check the label against, + /// and an unverifiable label is the failure mode this command exists to prevent. + /// + [Fact] + public async Task SdkExportRejectsASubstitutedPackageWhenTheCheckoutVersionIsUnknown() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", checkoutVersionPrefix: null); + + var checkoutVersion = provider.GetRequiredService().IdentitySdkVersion; + + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{checkoutVersion}"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + [Fact] public async Task SdkExportForAThirdPartyPackageIsUnaffectedByCheckoutSubstitution() { var interactionService = new TestInteractionService(); using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - appHostServerProject.LocalProjectSubstitutions["Aspire.Hosting.Redis"] = - Path.Combine("src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); var rpcClient = new StubExportRpcClient(); using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", CheckoutVersionPrefix(provider)); // A Community Toolkit integration is never replaced by a repository project, so it restores // at the requested version even from a checkout and must keep exporting. @@ -373,11 +449,20 @@ private ServiceProvider CreateProvider( TestInteractionService interactionService, TemporaryWorkspace workspace, IAppHostRpcClient rpcClient, - IAppHostServerProject appHostServerProject) + IAppHostServerProject appHostServerProject, + string? identityVersion = null, + bool identityOverridden = false) { var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper, options => { options.InteractionServiceFactory = _ => interactionService; + if (identityVersion is not null || identityOverridden) + { + options.CliExecutionContextFactory = _ => TestExecutionContextHelper.CreateExecutionContext( + workspace.WorkspaceRoot, + identityVersion: identityVersion, + identityOverridden: identityOverridden); + } }); services.AddSingleton(new TestAppHostServerProjectFactory @@ -392,6 +477,19 @@ private ServiceProvider CreateProvider( return services.BuildServiceProvider(); } + /// + /// The Major.Minor.Patch a checkout matching this CLI's identity would build. Tests that + /// exercise the honest local-development path need the substitution to agree with the identity. + /// + private static string CheckoutVersionPrefix(ServiceProvider provider) + { + var identity = SemVersion.Parse( + provider.GetRequiredService().IdentitySdkVersion, + SemVersionStyles.Any); + + return $"{identity.Major}.{identity.Minor}.{identity.Patch}"; + } + private sealed class StubExportRpcClient : FakeAppHostRpcClient { public (string Language, string PackageName, string PackageVersion)? LastExportRequest { get; private set; } diff --git a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs index 3ed71abb0ba..85e4b3b3219 100644 --- a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs @@ -346,6 +346,70 @@ public void FormatPretty_IncludesExportedValues() Assert.Contains("\"你好\"", output); } + /// + /// sdk dump reports the versions it was asked to scan, not the versions NuGet + /// resolved. That is deliberate and different from sdk export, which publishes documents + /// keyed on the version and therefore pins the restore. + /// + /// + /// Nothing consumes packages as a resolved identity: --format ci — the format the + /// checked-in *.ats.txt baselines use — omits the block entirely, and + /// generate-ats-diffs.yml passes .csproj paths, which carry no version at all. + /// + [Fact] + public void SdkDumpRecordsTheRequestedPackageVersionRatherThanTheResolvedOne() + { + Assert.True(SdkCommandPreparation.TryParseIntegrationArgument( + "Aspire.Hosting.Redis@13.4.0", + requireExactVersion: false, + out var reference, + out _, + out _)); + + // The restore is a NuGet minimum, so 13.4.1 can satisfy it while `packages` still says + // 13.4.0. Callers that need the two to agree use `sdk export`. + Assert.False(reference!.RequireExactVersion); + Assert.Equal("13.4.0", reference.GetRestoreVersionRange(forceExact: false)); + + var capabilities = new CapabilitiesInfo + { + Packages = [new PackageInfo { Name = reference.Name, Version = reference.Version! }] + }; + + using var document = JsonDocument.Parse(InvokeFormatter("FormatJson", capabilities)); + var package = Assert.Single(document.RootElement.GetProperty("Packages").EnumerateArray()); + Assert.Equal("Aspire.Hosting.Redis", package.GetProperty("Name").GetString()); + Assert.Equal("13.4.0", package.GetProperty("Version").GetString()); + } + + /// + /// The checked-in *.ats.txt baselines are produced with --format ci, which carries + /// no package versions at all. That is what keeps the requested-version semantics above from + /// reaching a version-keyed artifact. + /// + [Fact] + public void SdkDumpCiFormatCarriesNoPackageVersions() + { + var capabilities = new CapabilitiesInfo + { + Packages = [new PackageInfo { Name = "Aspire.Hosting.Redis", Version = "13.4.0" }] + }; + + var sections = InvokeFormatter("FormatCi", capabilities) + .Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries) + .Where(line => line.StartsWith('#')) + .ToArray(); + + Assert.Equal( + [ + "# Aspire Type System Capabilities", + "# Generated by: aspire sdk dump --format ci", + "# Handle Types", + "# Capabilities" + ], + sections); + } + private static string InvokeFormatter(string methodName, CapabilitiesInfo capabilities) { var method = typeof(SdkDumpCommand).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic); diff --git a/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs b/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs index 646321f32d6..109650b6dfa 100644 --- a/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs @@ -29,6 +29,43 @@ public void ProjectReference_HasProjectPathAndNoVersion() Assert.Equal("/path/to/MyIntegration.csproj", reference.ProjectPath); } + /// + /// A caller can write a NuGet range directly. Pinning it again would produce [[13.2.0]], + /// which NuGet rejects, so an already-bracketed version has to pass through untouched no matter + /// which side asked for exactness. + /// + [Theory] + [InlineData("[13.2.0]")] + [InlineData("[13.2.0,13.3.0)")] + [InlineData("(13.2.0,)")] + public void GetRestoreVersionRange_LeavesAnExplicitRangeAlone(string version) + { + Assert.Equal(version, IntegrationReference.FromPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: false)); + Assert.Equal(version, IntegrationReference.FromPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: true)); + Assert.Equal(version, IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: false)); + Assert.Equal(version, IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: true)); + } + + [Fact] + public void GetRestoreVersionRange_PinsOnlyWhenExactnessIsAskedFor() + { + var floating = IntegrationReference.FromPackage("Aspire.Hosting.Redis", "13.2.0"); + var exact = IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", "13.2.0"); + + Assert.Equal("13.2.0", floating.GetRestoreVersionRange(forceExact: false)); + Assert.Equal("[13.2.0]", floating.GetRestoreVersionRange(forceExact: true)); + Assert.Equal("[13.2.0]", exact.GetRestoreVersionRange(forceExact: false)); + Assert.Equal("[13.2.0]", exact.GetRestoreVersionRange(forceExact: true)); + } + + [Fact] + public void GetRestoreVersionRange_ThrowsForAProjectReference() + { + var reference = IntegrationReference.FromProject("MyIntegration", "/path/to/MyIntegration.csproj"); + + Assert.Throws(() => reference.GetRestoreVersionRange(forceExact: false)); + } + [Fact] public void GetIntegrationReferences_DetectsCsprojAsProjectReference() { diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs index f33538b3b7c..55a9df8b2c8 100644 --- a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.IO.Compression; using System.Xml.Linq; using Aspire.Cli.Configuration; using Aspire.Cli.Projects; @@ -69,9 +67,9 @@ public async Task CreateProjectFiles_ProducesAProjectThatRestores() // The template always references these two without a version, so they have to resolve // through the central list the way they do in the real repo. - CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); - CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); - CreateStubPackage(feedPath, IntegrationPackage, "13.4.0"); + OfflineNuGetFeed.CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); + OfflineNuGetFeed.CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); + OfflineNuGetFeed.CreateStubPackage(feedPath, IntegrationPackage, "13.4.0"); // Mirrors the real repo: a central list that pins first-party dependencies but knows nothing // about a Community Toolkit integration. @@ -89,7 +87,7 @@ await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), await project.CreateProjectFilesAsync( [IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")]); - var (exitCode, output) = await RestoreAsync( + var (exitCode, output) = await OfflineNuGetFeed.RestoreAsync( Path.Combine(projectModelPath, "AppHostServer.csproj"), feedPath); @@ -148,7 +146,7 @@ public void GetLocalProjectSubstitution_ReportsOnlyFirstPartyProjectsThatExist() var project = CreateProject(appPath, Path.Combine(appPath, ".aspire_server")); - Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("Aspire.Hosting.Redis")); + Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("Aspire.Hosting.Redis")?.ProjectPath); // No src/Aspire.Hosting.Qdrant in this checkout, so the package really is restored. Assert.Null(project.GetLocalProjectSubstitution("Aspire.Hosting.Qdrant")); @@ -157,6 +155,72 @@ public void GetLocalProjectSubstitution_ReportsOnlyFirstPartyProjectsThatExist() Assert.Null(project.GetLocalProjectSubstitution("CommunityToolkit.Aspire.Hosting.ActiveMQ")); } + /// + /// The version a checkout builds has to come from the checkout, because the version this CLI + /// reports is overrideable. eng/Versions.props is where the repository states it. + /// + [Fact] + public void GetLocalProjectSubstitution_ReportsTheVersionTheCheckoutBuilds() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + + var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); + File.WriteAllText(redisProjectPath, ""); + + var project = CreateProject(appPath, Path.Combine(appPath, ".aspire_server")); + + // No eng/Versions.props yet, so the checkout cannot say what it builds and callers that + // publish version-keyed artifacts have to treat the substitution as unverifiable. + Assert.Null(project.GetLocalProjectSubstitution("Aspire.Hosting.Redis")?.CheckoutVersionPrefix); + + Directory.CreateDirectory(Path.Combine(appPath, "eng")); + File.WriteAllText(Path.Combine(appPath, "eng", "Versions.props"), """ + + + 13 + 5 + 0 + + + """); + + var withVersions = CreateProject(appPath, Path.Combine(appPath, ".aspire_server_versioned")); + + Assert.Equal("13.5.0", withVersions.GetLocalProjectSubstitution("Aspire.Hosting.Redis")?.CheckoutVersionPrefix); + } + + /// + /// A first-party package name does not mean the checkout can supply it. Without a matching + /// project under src/ the reference used to be dropped from the generated project + /// entirely, so a nonexistent package scanned clean and exported an empty module. + /// + [Fact] + public async Task CreateProjectFiles_FallsBackToAPackageReferenceWhenTheLocalProjectIsMissing() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + var projectModelPath = Path.Combine(appPath, ".aspire_server"); + + var project = CreateProject(appPath, projectModelPath); + + await project.CreateProjectFilesAsync( + [ + IntegrationReference.FromExactPackage("Aspire.Hosting.NotInThisCheckout", "13.4.0"), + IntegrationReference.FromPackage("Aspire.Hosting.AlsoMissing", "13.4.0") + ]); + + var document = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")); + var references = document + .Descendants("PackageReference") + .ToDictionary(element => element.Attribute("Include")!.Value, element => element.Attribute("VersionOverride")?.Value); + + Assert.Equal("[13.4.0]", references["Aspire.Hosting.NotInThisCheckout"]); + Assert.Equal("13.4.0", references["Aspire.Hosting.AlsoMissing"]); + Assert.Empty(document.Descendants("ProjectReference")); + } + /// /// The generated XML cannot show what NuGet does with it. This restores twice against an offline /// feed that holds 13.4.1 but not the requested 13.4.0: the plain reference silently resolves @@ -172,9 +236,9 @@ public async Task CreateProjectFiles_ExactIntegrationDoesNotFloatToALaterPackage const string IntegrationPackage = "Contoso.Aspire.Hosting.ExactVersionProbe"; - CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); - CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); - CreateStubPackage(feedPath, IntegrationPackage, "13.4.1"); + OfflineNuGetFeed.CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); + OfflineNuGetFeed.CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); + OfflineNuGetFeed.CreateStubPackage(feedPath, IntegrationPackage, "13.4.1"); await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), """ @@ -189,7 +253,7 @@ await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), await CreateProject(appPath, floatingModelPath) .CreateProjectFilesAsync([IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")]); - var (floatingExitCode, floatingOutput) = await RestoreAsync( + var (floatingExitCode, floatingOutput) = await OfflineNuGetFeed.RestoreAsync( Path.Combine(floatingModelPath, "AppHostServer.csproj"), feedPath); outputHelper.WriteLine(floatingOutput); @@ -208,7 +272,7 @@ await File.ReadAllTextAsync(Path.Combine(floatingModelPath, "obj", "project.asse await CreateProject(appPath, exactModelPath) .CreateProjectFilesAsync([IntegrationReference.FromExactPackage(IntegrationPackage, "13.4.0")]); - var (exactExitCode, exactOutput) = await RestoreAsync( + var (exactExitCode, exactOutput) = await OfflineNuGetFeed.RestoreAsync( Path.Combine(exactModelPath, "AppHostServer.csproj"), feedPath); outputHelper.WriteLine(exactOutput); @@ -230,59 +294,4 @@ private static DotNetBasedAppHostServerProject CreateProject(string appPath, str new TestEnvironment(), NullLogger.Instance, projectModelPath); - - private static void CreateStubPackage(string feedPath, string id, string version) - { - var stagingPath = Path.Combine(feedPath, $".staging-{id}"); - Directory.CreateDirectory(Path.Combine(stagingPath, "lib", "net10.0")); - - File.WriteAllText(Path.Combine(stagingPath, $"{id}.nuspec"), $""" - - - - {id} - {version} - Stub package for restore tests. - Aspire - - - """); - - File.WriteAllText(Path.Combine(stagingPath, "[Content_Types].xml"), """ - - - - - - - """); - - File.WriteAllBytes(Path.Combine(stagingPath, "lib", "net10.0", $"{id}.dll"), []); - - ZipFile.CreateFromDirectory(stagingPath, Path.Combine(feedPath, $"{id}.{version}.nupkg")); - Directory.Delete(stagingPath, recursive: true); - } - - private static async Task<(int ExitCode, string Output)> RestoreAsync(string projectPath, string feedPath) - { - var startInfo = new ProcessStartInfo("dotnet") - { - RedirectStandardOutput = true, - RedirectStandardError = true, - WorkingDirectory = Path.GetDirectoryName(projectPath)! - }; - - startInfo.ArgumentList.Add("restore"); - startInfo.ArgumentList.Add(projectPath); - // Replaces every configured source so the restore cannot reach the network. - startInfo.ArgumentList.Add("--source"); - startInfo.ArgumentList.Add(feedPath); - - using var process = Process.Start(startInfo)!; - var stdoutTask = process.StandardOutput.ReadToEndAsync(); - var stderrTask = process.StandardError.ReadToEndAsync(); - await process.WaitForExitAsync(); - - return (process.ExitCode, await stdoutTask + await stderrTask); - } } diff --git a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs index adbb03eb890..5d34d1e00d0 100644 --- a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs @@ -65,6 +65,78 @@ public void GenerateIntegrationProjectFile_PinsExactPackagesToASingleVersionRang Assert.Equal("13.2.0", versions["Aspire.Hosting"]); } + /// + /// The generated XML cannot show what NuGet does with it, and the package-only install path never + /// touches the repository scanner, so the pin has to be proven here too. This restores twice + /// against an offline feed that holds 13.4.1 but not the requested 13.4.0. + /// + [Fact] + public async Task GenerateIntegrationProjectFile_ExactPackageDoesNotFloatToALaterPackage() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var root = workspace.WorkspaceRoot.FullName; + var feedPath = Path.Combine(root, "feed"); + Directory.CreateDirectory(feedPath); + + const string IntegrationPackage = "Contoso.Aspire.Hosting.PrebuiltExactProbe"; + OfflineNuGetFeed.CreateStubPackage(feedPath, IntegrationPackage, "13.4.1"); + + var floatingPath = await WriteIntegrationProjectAsync( + root, + "floating", + IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")); + var (floatingExitCode, floatingOutput) = await OfflineNuGetFeed.RestoreAsync(floatingPath, feedPath); + outputHelper.WriteLine(floatingOutput); + + // NU1603 is NuGet reporting that it resolved something other than what was asked for. The + // assets file records which version won, which the console output does not always spell out. + Assert.Equal(0, floatingExitCode); + Assert.Contains("NU1603", floatingOutput, StringComparison.Ordinal); + Assert.Contains( + $"{IntegrationPackage}/13.4.1", + await File.ReadAllTextAsync(Path.Combine(Path.GetDirectoryName(floatingPath)!, "obj", "project.assets.json")), + StringComparison.Ordinal); + + var exactPath = await WriteIntegrationProjectAsync( + root, + "exact", + IntegrationReference.FromExactPackage(IntegrationPackage, "13.4.0")); + var (exactExitCode, exactOutput) = await OfflineNuGetFeed.RestoreAsync(exactPath, feedPath); + outputHelper.WriteLine(exactOutput); + + // NU1102 is "package found but not at the requested version", which is the failure a caller + // needs instead of a document labelled 13.4.0 that describes 13.4.1. + Assert.NotEqual(0, exactExitCode); + Assert.Contains("NU1102", exactOutput, StringComparison.Ordinal); + } + + /// + /// Writes the prebuilt closure project the way BuildIntegrationClosureManifestAsync does, + /// including the surrounding files that keep the restore from importing the enclosing repository. + /// + private static async Task WriteIntegrationProjectAsync(string root, string name, IntegrationReference reference) + { + var restoreDir = Path.Combine(root, $"integration-restore-{name}"); + Directory.CreateDirectory(restoreDir); + + var projectPath = Path.Combine(restoreDir, "IntegrationClosure.csproj"); + await File.WriteAllTextAsync( + projectPath, + PrebuiltAppHostServer.GenerateIntegrationProjectFile([reference], [], restoreDir)); + + await File.WriteAllTextAsync(Path.Combine(restoreDir, "Directory.Packages.props"), """ + + + false + + + """); + await File.WriteAllTextAsync(Path.Combine(restoreDir, "Directory.Build.props"), ""); + await File.WriteAllTextAsync(Path.Combine(restoreDir, "Directory.Build.targets"), ""); + + return projectPath; + } + [Fact] public void GenerateIntegrationProjectFile_WithProjectRefsOnly_ProducesProjectReferences() { @@ -1172,6 +1244,48 @@ public async Task PrepareAsync_WithPackageReferences_UsesPackageSourceOverride() } } + [Fact] + public async Task PrepareAsync_WithExactPackageReference_PinsBundledRestoreWithoutASourceOverride() + { + // `sdk export` restores through the bundled NuGet helper on an installed CLI, and that path + // never sees the generated closure project. Pin the argument it is actually handed. + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + List? restoreArgs = null; + + var (server, executionFactory) = CreatePackageReferenceServer(workspace); + executionFactory.AssertionCallback = (args, _, _, _) => + { + if (args is ["nuget", "restore", ..]) + { + restoreArgs = [.. args]; + } + }; + + var workingDirectory = GetWorkingDirectory(server); + + try + { + var result = await server.PrepareAsync( + "13.4.0", + [ + IntegrationReference.FromExactPackage("CommunityToolkit.Aspire.Hosting.Redis", "13.4.0"), + IntegrationReference.FromPackage("CommunityToolkit.Aspire.Hosting.Dapr", "13.4.0") + ]); + + Assert.True(result.Success); + Assert.NotNull(restoreArgs); + + // No `--source`, so the historical Aspire*-only pinning does not apply and the exactness + // has to come from the reference itself. + Assert.Contains("CommunityToolkit.Aspire.Hosting.Redis,[13.4.0]", restoreArgs!); + Assert.Contains("CommunityToolkit.Aspire.Hosting.Dapr,13.4.0", restoreArgs!); + } + finally + { + DeleteWorkingDirectory(workingDirectory); + } + } + [Fact] public async Task PrepareAsync_WithPackageSourceOverride_AddsNuGetOrgFallbackSource() { @@ -1629,7 +1743,11 @@ await File.WriteAllTextAsync(aspireConfigPath, """ var combined = string.Join('\n', result.Output!.GetLines().Select(static line => line.Line)); Assert.Contains($"--source: {packageSourceOverride}", combined); Assert.Contains("channel: daily", combined); - Assert.Contains("packages: Aspire.Hosting.CodeGeneration.TypeScript 13.4.0-pr.17141.gf142085f", combined); + + // The footer has to show the range restore was actually given. `--source` pins Aspire + // packages, so printing the raw version would send a reader looking for a resolution + // failure that the bracketed form explains immediately. + Assert.Contains("packages: Aspire.Hosting.CodeGeneration.TypeScript [13.4.0-pr.17141.gf142085f]", combined); } finally { @@ -1666,11 +1784,12 @@ public async Task PrepareAsync_RestoreFailure_WithManyPackages_TruncatesPackageL Assert.NotNull(result.Output); var combined = string.Join('\n', result.Output!.GetLines().Select(static line => line.Line)); - // First five packages appear; later ones are collapsed into a count. - Assert.Contains("Aspire.Hosting.Pkg0 1.0.0", combined); - Assert.Contains("Aspire.Hosting.Pkg4 1.0.0", combined); - Assert.DoesNotContain("Aspire.Hosting.Pkg5 1.0.0", combined); - Assert.DoesNotContain("Aspire.Hosting.Pkg7 1.0.0", combined); + // First five packages appear; later ones are collapsed into a count. Versions show the + // effective restore range because `--source` pins Aspire packages exactly. + var packagesLine = Assert.Single(result.Output!.GetLines().Select(static line => line.Line), static line => line.Contains("packages:", StringComparison.Ordinal)); + Assert.Equal( + " packages: Aspire.Hosting.Pkg0 [1.0.0], Aspire.Hosting.Pkg1 [1.0.0], Aspire.Hosting.Pkg2 [1.0.0], Aspire.Hosting.Pkg3 [1.0.0], Aspire.Hosting.Pkg4 [1.0.0], … (+3 more)", + packagesLine); Assert.Contains("(+3 more)", combined); } finally diff --git a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs index 9e7c8ff762e..f25cac548cb 100644 --- a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs +++ b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs @@ -17,17 +17,26 @@ internal sealed class FakeSucceedingAppHostServerProject(string appDirectoryPath public string AppDirectoryPath { get; } = appDirectoryPath; /// - /// Package names this fake reports as satisfied by a repository project, keyed to the project - /// path. Mirrors in repository dev mode, where an + /// Package names this fake reports as satisfied by a repository project. Mirrors + /// in repository dev mode, where an /// Aspire.Hosting.* package reference is replaced by the matching project under /// src/ and the requested package version is discarded. /// - public Dictionary LocalProjectSubstitutions { get; } = new(StringComparer.OrdinalIgnoreCase); + public Dictionary LocalProjectSubstitutions { get; } = new(StringComparer.OrdinalIgnoreCase); + + /// + /// Registers a substitution whose checkout builds , or + /// whose version cannot be established when that is . + /// + public void AddLocalProjectSubstitution(string packageName, string? checkoutVersionPrefix) + => LocalProjectSubstitutions[packageName] = new LocalProjectSubstitution( + Path.Combine("src", packageName, $"{packageName}.csproj"), + checkoutVersionPrefix); public string GetInstanceIdentifier() => AppDirectoryPath; - public string? GetLocalProjectSubstitution(string packageName) - => LocalProjectSubstitutions.TryGetValue(packageName, out var projectPath) ? projectPath : null; + public LocalProjectSubstitution? GetLocalProjectSubstitution(string packageName) + => LocalProjectSubstitutions.TryGetValue(packageName, out var substitution) ? substitution : null; public Task PrepareAsync( string sdkVersion, diff --git a/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs b/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs new file mode 100644 index 00000000000..37311f3647f --- /dev/null +++ b/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs @@ -0,0 +1,87 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.IO.Compression; + +namespace Aspire.Cli.Tests.Utils; + +/// +/// A folder-backed NuGet feed built from fabricated packages, plus a restore that can only reach it. +/// +/// +/// Version-range behavior is decided by NuGet, not by the XML the CLI generates, so the only way to +/// prove a pin holds is to restore against a feed whose contents are known exactly. Package ids used +/// with this helper must not exist on any real feed or in the developer's global package cache, or a +/// restore that should fail can succeed from the cache instead. +/// +internal static class OfflineNuGetFeed +{ + /// + /// Writes a minimal but valid .nupkg for at + /// into . + /// + public static void CreateStubPackage(string feedPath, string id, string version) + { + var stagingPath = Path.Combine(feedPath, $".staging-{id}"); + Directory.CreateDirectory(Path.Combine(stagingPath, "lib", "net10.0")); + + File.WriteAllText(Path.Combine(stagingPath, $"{id}.nuspec"), $""" + + + + {id} + {version} + Stub package for restore tests. + Aspire + + + """); + + File.WriteAllText(Path.Combine(stagingPath, "[Content_Types].xml"), """ + + + + + + + """); + + File.WriteAllBytes(Path.Combine(stagingPath, "lib", "net10.0", $"{id}.dll"), []); + + ZipFile.CreateFromDirectory(stagingPath, Path.Combine(feedPath, $"{id}.{version}.nupkg")); + Directory.Delete(stagingPath, recursive: true); + } + + /// + /// Restores against only. + /// + /// + /// --source replaces every configured source rather than adding one, which is what keeps + /// the restore offline. Note that it does not isolate the global packages folder: + /// --packages would, but it also breaks targeting-pack resolution + /// (NU1101 Microsoft.NETCore.App.Ref), so fabricated package ids are used instead. + /// + public static async Task<(int ExitCode, string Output)> RestoreAsync(string projectPath, string feedPath) + { + var startInfo = new ProcessStartInfo("dotnet") + { + RedirectStandardOutput = true, + RedirectStandardError = true, + WorkingDirectory = Path.GetDirectoryName(projectPath)! + }; + + startInfo.ArgumentList.Add("restore"); + startInfo.ArgumentList.Add(projectPath); + startInfo.ArgumentList.Add("--source"); + startInfo.ArgumentList.Add(feedPath); + + using var process = Process.Start(startInfo)!; + // Read both streams concurrently to avoid deadlock when a pipe buffer fills. + var stdoutTask = process.StandardOutput.ReadToEndAsync(); + var stderrTask = process.StandardError.ReadToEndAsync(); + await process.WaitForExitAsync(); + + return (process.ExitCode, await stdoutTask + await stderrTask); + } +} From d204a1bf188637065c627e209c57a34ef8fc08fd Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 10:53:28 -0400 Subject: [PATCH 18/73] Check the core export against the checkout, not just the identity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Self-review of the previous two commits turned up four holes, one of which reopened after the first fix. `sdk export` with no `--package` exports Aspire.Hosting at the CLI's own identity version, and neither scanner honours a requested SDK version: the repository scanner builds src/Aspire.Hosting and the prebuilt scanner loads the assemblies bundled with the CLI. The only guard compared the request against the identity, but the default request *is* the identity, so it could only ever catch an explicitly wrong `--package`. Two things walked past it. An identity override makes the identity itself caller-controlled, so `ASPIRE_CLI_VERSION=99.0.0 aspire sdk export` published the current core surface as 99.0.0. And repository mode is entered through ASPIRE_REPO_ROOT, which is not an identity field at all, so an installed 13.4.0 CLI pointed at a 13.5.0 checkout mislabelled the export with no override in sight. The override is now refused outright, because the prebuilt scanner has no second signal to check it against, and the core package otherwise falls through to the same checkout-version comparison every other first-party package already got. The package-reference fallback for a first-party name with no project under src/ is now taken only when the caller demands an exact version. CreateProjectFile is shared with `aspire run`, `sdk dump`, `sdk generate` and the scaffolder, whose integrations come from aspire.config.json, where a version-less entry resolves to this CLI's identity — a version that can never restore from a feed. Failing there would have turned one unavailable integration into a build failure for the whole AppHost. Only `sdk export` asks for exactness, and only it names the package itself, so the empty-module bug stays fixed without the blast radius. The offline restore helper installed its fabricated packages into the real global packages folder, leaving 0-byte streamjsonrpc/1.0.0 and google.protobuf/1.0.0 stubs behind for good — NuGet never re-downloads a version it already has. It now restores into a throwaway folder, with the real one supplied as a fallback so targeting packs still resolve. Finally, the substitution test only passed because this build stamps -dev on the informational version; an official release build strips it and the export would have been allowed. Both halves are pinned now, so the rejection turns on the checkout-versus-request mismatch the test name describes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../Commands/Sdk/SdkExportCommand.cs | 31 +++++- .../DotNetBasedAppHostServerProject.cs | 15 ++- .../Commands/Sdk/SdkExportCommandTests.cs | 103 +++++++++++++++++- ...BasedAppHostServerPackageReferenceTests.cs | 16 ++- .../Utils/OfflineNuGetFeed.cs | 75 +++++++++++-- 5 files changed, 216 insertions(+), 24 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 900d9baf335..09b869b812a 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -213,9 +213,8 @@ private static string StripBuildMetadata(string version) /// discards the requested version, so the checkout's API surface would be published under /// someone else's version number. That is the same stale-signature problem the core-package /// guard prevents, so this refuses for the same reason. Asking for the version this CLI was - /// built from is still allowed: that is exactly what the checkout contains. The core package is - /// already handled before any project is created, and third-party packages are never - /// substituted, so both fall straight through. + /// built from is still allowed: that is exactly what the checkout contains. Third-party packages + /// are never substituted, so they fall straight through. /// /// /// The check cannot rest on alone, because @@ -224,6 +223,22 @@ private static string StripBuildMetadata(string version) /// the independent half; the identity is still compared so a checkout on the right line cannot /// publish a neighbouring build's number. /// + /// + /// The core package needs both halves as well. Neither + /// implementation honours the requested SDK version — the repository scanner builds + /// src/Aspire.Hosting and the prebuilt scanner loads the assemblies bundled with the CLI + /// — so a core export always describes this CLI, and the label has to be this CLI's real + /// version. The comparison that enforces that runs before any project is created, but it + /// compares the request against the identity while the default request is the identity, + /// so on its own it only catches an explicitly wrong --package. Two cases get past it. + /// An identity override makes the identity itself caller-controlled, and the prebuilt scanner + /// has no second signal to check it against, so an override is refused outright. Repository mode + /// is entered through ASPIRE_REPO_ROOT, which is not an identity field at all, so an + /// installed CLI can be pointed at a checkout on a different version line with no override in + /// effect; the core package therefore falls through to the same checkout comparison every other + /// first-party package gets, which is available because src/Aspire.Hosting is always + /// project-referenced by the generated scanner. + /// /// /// The scanner AppHost that will restore the export. /// The package being exported. @@ -231,9 +246,15 @@ private static string StripBuildMetadata(string version) /// The rejection reason, or when the request is exportable. private string? ValidateRequestedPackageIsRestorable(IAppHostServerProject serverProject, string packageName, string packageVersion) { - if (string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase) + && ExecutionContext.IdentityOverridden) { - return null; + // The prebuilt scanner has no second signal: the core assemblies come from the bundle + // this CLI shipped with, so an override leaves nothing to check the label against. + // Repository mode does have one, and falls through to it below. + return $"The scanner loads the {CorePackageName} assemblies this CLI ships with, so an export of it describes this CLI. " + + $"This run emulates a different build through an ASPIRE_CLI_* override, so the export cannot be attributed to a real build of {packageVersion}. " + + $"Re-run without the override, or export {CorePackageName} from an installed CLI."; } if (serverProject.GetLocalProjectSubstitution(packageName) is not { } substitution) diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index 0cb3eaf1663..b283c3bde61 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -197,17 +197,26 @@ private XDocument CreateProjectFile(IEnumerable integratio new XElement("IsAspireProjectResource", "false"))); } } - else + else if (integration.RequireExactVersion) { // A first-party name does not mean this checkout can supply it. Dropping the - // reference here used to make a nonexistent package scan clean and export an - // empty module, so fall back to restoring it like any other package. + // reference made `sdk export --package Aspire.Hosting.DoesNotExist@13.5.0-dev` + // scan clean and publish an empty module under a package id that has never + // existed, so a caller that demands an exact version gets a real package + // reference instead and the restore fails (NU1101) as it should. if (integration.Version is null) { throw new InvalidOperationException($"Integration '{integration.Name}' is neither a project reference nor a package reference (both Version and ProjectPath are null)."); } otherPackages.Add(integration); } + + // Everything else keeps dropping the reference. Only `sdk export` asks for exactness, + // and only it names the package explicitly; `aspire run`, `sdk dump`, and `sdk + // generate` take their integrations from aspire.config.json, where a version-less + // entry resolves to this CLI's identity (`13.5.0-dev` in a checkout). Restoring that + // as a package could never succeed, so failing here would turn one unavailable + // integration into a build failure for the whole AppHost. } else { diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index c10192042c7..e582fcb8398 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -207,13 +207,21 @@ public async Task SdkExportForAPackageTheCheckoutWouldSubstituteReturnsInvalidCo using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", CheckoutVersionPrefix(provider)); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.5.0"); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", "13.5.0"); // A CLI running from a repository checkout builds first-party integrations from src/ and - // throws the requested package version away, so honouring this would publish the checkout's - // API surface under 13.5.0 — the mislabel this command exists to prevent. - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + // throws the requested package version away, so honouring this would publish the 13.5.0 + // checkout's API surface under 13.4.0 — the mislabel this command exists to prevent. Both + // halves are pinned rather than derived from the running assembly so the rejection turns on + // the checkout-versus-request mismatch and not on whether this build carries a prerelease + // label, which an official release build strips. + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.4.0"); Assert.Equal(CliExitCodes.InvalidCommand, exitCode); Assert.Null(rpcClient.LastExportRequest); @@ -318,6 +326,91 @@ public async Task SdkExportRejectsASubstitutedPackageWhenTheCheckoutVersionIsUnk Assert.Empty(interactionService.DisplayedRawText); } + /// + /// Neither scanner honours the requested SDK version — the repository scanner builds + /// src/Aspire.Hosting and the prebuilt scanner loads the assemblies bundled with the CLI + /// — so a core export always describes this CLI. The version guard that enforces that compares + /// the request against the identity, which an override also controls, and the default request is + /// that same identity, so the comparison is vacuous under an override. + /// + [Fact] + public async Task SdkExportOfTheCorePackageRejectsAnOverriddenCliIdentity() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "99.0.0", + identityOverridden: true); + + // No --package at all, so this is the default invocation: Aspire.Hosting at the identity + // version. Without the guard this publishes the current core surface as 99.0.0. + var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + + /// + /// Repository mode is entered through ASPIRE_REPO_ROOT, which is not an identity field, + /// so an installed CLI pointed at a checkout on another version line has an entirely honest + /// identity and no override in effect. The generated scanner always project-references + /// src/Aspire.Hosting, so what it exports is the checkout's core surface under the + /// installed CLI's number. + /// + [Fact] + public async Task SdkExportOfTheCorePackageRejectsACheckoutOnAnotherVersionLine() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.4.0"); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + + /// + /// The same checkout on the same version line is exactly what the label claims, so it exports. + /// + [Fact] + public async Task SdkExportOfTheCorePackageFromAMatchingCheckoutSucceeds() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.5.0"); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal("Aspire.Hosting", rpcClient.LastExportRequest?.PackageName); + Assert.Equal("13.5.0", rpcClient.LastExportRequest?.PackageVersion); + } + [Fact] public async Task SdkExportForAThirdPartyPackageIsUnaffectedByCheckoutSubstitution() { diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs index 55a9df8b2c8..447adb7abfc 100644 --- a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs @@ -193,11 +193,19 @@ public void GetLocalProjectSubstitution_ReportsTheVersionTheCheckoutBuilds() /// /// A first-party package name does not mean the checkout can supply it. Without a matching - /// project under src/ the reference used to be dropped from the generated project - /// entirely, so a nonexistent package scanned clean and exported an empty module. + /// project under src/ the reference is dropped from the generated project, so a + /// nonexistent package scanned clean and exported an empty module. A reference that demands an + /// exact version now restores as a real package instead, so the failure surfaces. /// + /// + /// Only sdk export demands exactness. Everything else keeps dropping the reference, + /// because aspire run and the other scanner callers take their integrations from + /// aspire.config.json, where a version-less entry resolves to this CLI's identity — a version + /// that could never restore from a feed, so failing would break the whole AppHost rather than + /// one integration. + /// [Fact] - public async Task CreateProjectFiles_FallsBackToAPackageReferenceWhenTheLocalProjectIsMissing() + public async Task CreateProjectFiles_FallsBackToAPackageReferenceOnlyForAnExactReference() { using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appPath = workspace.WorkspaceRoot.FullName; @@ -217,7 +225,7 @@ await project.CreateProjectFilesAsync( .ToDictionary(element => element.Attribute("Include")!.Value, element => element.Attribute("VersionOverride")?.Value); Assert.Equal("[13.4.0]", references["Aspire.Hosting.NotInThisCheckout"]); - Assert.Equal("13.4.0", references["Aspire.Hosting.AlsoMissing"]); + Assert.False(references.ContainsKey("Aspire.Hosting.AlsoMissing")); Assert.Empty(document.Descendants("ProjectReference")); } diff --git a/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs b/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs index 37311f3647f..28337808214 100644 --- a/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs +++ b/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs @@ -11,9 +11,12 @@ namespace Aspire.Cli.Tests.Utils; /// /// /// Version-range behavior is decided by NuGet, not by the XML the CLI generates, so the only way to -/// prove a pin holds is to restore against a feed whose contents are known exactly. Package ids used -/// with this helper must not exist on any real feed or in the developer's global package cache, or a -/// restore that should fail can succeed from the cache instead. +/// prove a pin holds is to restore against a feed whose contents are known exactly. +/// installs into a throwaway global packages folder so the fabricated +/// packages never enter the developer's or the agent's real cache. Reads are not isolated — the real +/// folder is supplied as a fallback so targeting packs still resolve, and NuGet treats a fallback +/// folder as a resolution source — so package ids used with this helper must still not exist on any +/// real feed or in the real cache, or a restore that should fail can succeed from it instead. /// internal static class OfflineNuGetFeed { @@ -54,16 +57,29 @@ public static void CreateStubPackage(string feedPath, string id, string version) } /// - /// Restores against only. + /// Restores against only, into a + /// throwaway global packages folder. /// /// + /// /// --source replaces every configured source rather than adding one, which is what keeps - /// the restore offline. Note that it does not isolate the global packages folder: - /// --packages would, but it also breaks targeting-pack resolution - /// (NU1101 Microsoft.NETCore.App.Ref), so fabricated package ids are used instead. + /// the restore offline. + /// + /// + /// --packages then keeps the fabricated packages out of the real global packages folder. + /// Without it they are installed under their stated ids for good — NuGet never re-downloads a + /// version already present — so a stub built here would silently satisfy a later restore + /// anywhere on the machine. On its own --packages also hides the targeting packs the + /// project needs (NU1101 Microsoft.NETCore.App.Ref), so the real folder is supplied as a + /// fallback: lookups find it there, installs still go to the throwaway folder. A fallback folder + /// that does not exist is a hard NU1301, hence the create. + /// See https://learn.microsoft.com/nuget/consume-packages/managing-the-global-packages-and-cache-folders. + /// /// public static async Task<(int ExitCode, string Output)> RestoreAsync(string projectPath, string feedPath) { + using var packagesDirectory = new TempDirectory(); + var startInfo = new ProcessStartInfo("dotnet") { RedirectStandardOutput = true, @@ -71,10 +87,14 @@ public static void CreateStubPackage(string feedPath, string id, string version) WorkingDirectory = Path.GetDirectoryName(projectPath)! }; + startInfo.Environment["NUGET_FALLBACK_PACKAGES"] = EnsureGlobalPackagesFolder(); + startInfo.ArgumentList.Add("restore"); startInfo.ArgumentList.Add(projectPath); startInfo.ArgumentList.Add("--source"); startInfo.ArgumentList.Add(feedPath); + startInfo.ArgumentList.Add("--packages"); + startInfo.ArgumentList.Add(packagesDirectory.Path); using var process = Process.Start(startInfo)!; // Read both streams concurrently to avoid deadlock when a pipe buffer fills. @@ -84,4 +104,45 @@ public static void CreateStubPackage(string feedPath, string id, string version) return (process.ExitCode, await stdoutTask + await stderrTask); } + + /// + /// The real global packages folder, used as a fallback so targeting packs still resolve. + /// + /// + /// NUGET_PACKAGES wins when it is set, which is how CI relocates the folder; otherwise + /// NuGet's default is ~/.nuget/packages on every platform. The directory is created when + /// absent because NuGet fails a restore outright (NU1301) on a fallback folder that does + /// not exist. + /// + private static string EnsureGlobalPackagesFolder() + { + var folder = Environment.GetEnvironmentVariable("NUGET_PACKAGES") is { Length: > 0 } configured + ? configured + : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages"); + + Directory.CreateDirectory(folder); + return folder; + } + + /// + /// A directory that is deleted when the restore that used it is done. + /// + private sealed class TempDirectory : IDisposable + { + private readonly DirectoryInfo _directory = Directory.CreateTempSubdirectory("aspire-offline-feed"); + + public string Path => _directory.FullName; + + public void Dispose() + { + try + { + _directory.Delete(recursive: true); + } + catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) + { + // A leftover throwaway folder is harmless; failing the test over it is not. + } + } + } } From 5641913134294952063f6c3bd00325aa958500d1 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 11:04:58 -0400 Subject: [PATCH 19/73] Resolve the core substitution under its canonical name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core package is matched case-insensitively but the substitution was looked up under whatever the caller typed, and the real lookup resolves through File.Exists. So on Linux — the platform the docs pipeline runs on — `--package aspire.hosting@13.4.0` missed `src/aspire.hosting/`, the check returned "nothing to verify", and the export went ahead. The scanner meanwhile project-references src/Aspire.Hosting from a hardcoded canonical path no matter how the package was spelled, so it still built the checkout's core surface: exactly the mislabel the canonically-spelled form now blocks. Core is the only name whose project reference is added through a separate path, which is what let the check diverge from what the scanner actually did. The test fake's substitution dictionary was case-insensitive, which absorbed the bug the same way macOS and Windows do. It is ordinal now so the strictest platform is what every test sees. The prefix-mismatch message also needed to branch. A core export takes its version from this CLI's identity rather than from --package, so "run the export with the 13.4.0 CLI instead" named the CLI the user was already running. There the checkout is the half that has to move. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../Commands/Sdk/SdkExportCommand.cs | 29 +++++++++++++----- .../Commands/Sdk/SdkExportCommandTests.cs | 30 +++++++++++++++++++ .../FakeSucceedingAppHostServerProject.cs | 9 +++++- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 09b869b812a..224d65df8a7 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -246,8 +246,9 @@ private static string StripBuildMetadata(string version) /// The rejection reason, or when the request is exportable. private string? ValidateRequestedPackageIsRestorable(IAppHostServerProject serverProject, string packageName, string packageVersion) { - if (string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase) - && ExecutionContext.IdentityOverridden) + var isCorePackage = string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase); + + if (isCorePackage && ExecutionContext.IdentityOverridden) { // The prebuilt scanner has no second signal: the core assemblies come from the bundle // this CLI shipped with, so an override leaves nothing to check the label against. @@ -257,12 +258,19 @@ private static string StripBuildMetadata(string version) $"Re-run without the override, or export {CorePackageName} from an installed CLI."; } - if (serverProject.GetLocalProjectSubstitution(packageName) is not { } substitution) + // The core package is matched case-insensitively but resolved through the filesystem, and + // the generated scanner project-references src/Aspire.Hosting under that exact spelling no + // matter how the caller spelled it. Looking the substitution up under the caller's spelling + // would miss on a case-sensitive filesystem — `--package aspire.hosting` on Linux — and skip + // the whole check while the scanner still built the checkout's core surface. + var lookupName = isCorePackage ? CorePackageName : packageName; + + if (serverProject.GetLocalProjectSubstitution(lookupName) is not { } substitution) { return null; } - var preamble = $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {substitution.ProjectPath} " + + var preamble = $"This CLI runs from an Aspire repository checkout, so {lookupName} is built from {substitution.ProjectPath} " + $"instead of being restored from a package feed."; if (ExecutionContext.IdentityOverridden) @@ -283,9 +291,16 @@ private static string StripBuildMetadata(string version) if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out var requestedVersion) || $"{requestedVersion.Major}.{requestedVersion.Minor}.{requestedVersion.Patch}" != checkoutPrefix) { - return $"{preamble} That checkout builds {checkoutPrefix}, but {packageVersion} was requested, and exporting it " + - $"would describe the checkout's API surface under the requested version. " + - $"Run the export with the {StripBuildMetadata(packageVersion)} CLI instead."; + // A core export takes its version from this CLI's identity rather than from --package, + // so telling the caller to re-run with the requested version's CLI would name the CLI + // they are already running. There the checkout is the half that has to move. + return isCorePackage + ? $"{preamble} That checkout builds {checkoutPrefix}, but this CLI is {packageVersion}, and exporting it " + + $"would describe the checkout's API surface under this CLI's version. " + + $"Export {lookupName} from a {checkoutPrefix} CLI, or point this one at a {StripBuildMetadata(packageVersion)} checkout." + : $"{preamble} That checkout builds {checkoutPrefix}, but {packageVersion} was requested, and exporting it " + + $"would describe the checkout's API surface under the requested version. " + + $"Run the export with the {StripBuildMetadata(packageVersion)} CLI instead."; } var requested = StripBuildMetadata(packageVersion); diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index e582fcb8398..ae626ac759f 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -386,6 +386,36 @@ public async Task SdkExportOfTheCorePackageRejectsACheckoutOnAnotherVersionLine( Assert.Empty(interactionService.DisplayedRawText); } + /// + /// The core package is matched case-insensitively but resolved through the filesystem, and the + /// generated scanner project-references src/Aspire.Hosting under that exact spelling + /// regardless of how the caller spelled it. A lookup under the caller's spelling would miss on + /// a case-sensitive filesystem and skip the check while the scanner still built the checkout. + /// + [Fact] + public async Task SdkExportOfTheCorePackageRejectsACheckoutOnAnotherVersionLineWhateverTheCasing() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.4.0"); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); + + // The version has to match the identity or the earlier core guard rejects it for a different + // reason, which would hide whether the substitution lookup found anything. + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package aspire.hosting@13.4.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + /// /// The same checkout on the same version line is exactly what the label claims, so it exports. /// diff --git a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs index f25cac548cb..f3106fbad38 100644 --- a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs +++ b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs @@ -22,7 +22,14 @@ internal sealed class FakeSucceedingAppHostServerProject(string appDirectoryPath /// Aspire.Hosting.* package reference is replaced by the matching project under /// src/ and the requested package version is discarded. /// - public Dictionary LocalProjectSubstitutions { get; } = new(StringComparer.OrdinalIgnoreCase); + /// + /// The comparer is ordinal on purpose. The real implementation resolves a substitution through + /// File.Exists, so it is case-sensitive on Linux and case-insensitive on macOS and + /// Windows. Modelling the strictest platform here means a caller that looks a substitution up + /// under an arbitrary spelling fails everywhere rather than only on the platform CI happens not + /// to be running. + /// + public Dictionary LocalProjectSubstitutions { get; } = new(StringComparer.Ordinal); /// /// Registers a substitution whose checkout builds , or From 56ffd1a10664857f68152d43c11a8a603cc5a012 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 11:49:03 -0400 Subject: [PATCH 20/73] Settle the package id's spelling before anything acts on it A NuGet package id is case-insensitive; the things this command hands one to are not. The substitution probe resolved it through the filesystem, the generated scanner project-references src/Aspire.Hosting under the canonical spelling whatever was asked for, and the exported document records the string verbatim as the identity documentation is keyed on. The core name is now canonicalized once, where --package is parsed, so the guard, the scanner, and the label all describe one package. Doing it inside the guard covered the bypass but left `--package aspire.hosting` publishing a canonical document titled "aspire.hosting", which is not a package anyone can look up. The probe itself is the general case: `aspire.hosting.redis` found nothing on Linux and src/Aspire.Hosting.Redis on macOS and Windows, so the caller's spelling decided whether the checkout was substituted at all, and a caller publishing version-keyed artifacts was told there was nothing to guard against. It now matches the directory case-insensitively and returns the on-disk spelling, so the check and the generated project name the same project. The listing settles it on every platform: probing the caller's spelling would have handed their casing back wherever File.Exists ignores case. The test fake stays ordinal, which is now stricter than the real implementation. That keeps the command's own canonicalization under test rather than resting on the probe, which matters because the prebuilt scanner reports no substitution at all. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkExportCommand.cs | 32 ++++++---- .../DotNetBasedAppHostServerProject.cs | 43 +++++++++++-- .../Commands/Sdk/SdkExportCommandTests.cs | 31 +++++++++ ...BasedAppHostServerPackageReferenceTests.cs | 63 +++++++++++++++++++ .../FakeSucceedingAppHostServerProject.cs | 11 ++-- 5 files changed, 159 insertions(+), 21 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 224d65df8a7..5ce8f2dfdea 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -115,12 +115,23 @@ protected override async Task ExecuteAsync(ParseResult parseResul $"Invalid package '{package}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@13.5.0); project references are not supported by sdk export."); } - packageName = reference.Name; packageVersion = reference.Version; + // NuGet package ids are case-insensitive, so `aspire.hosting` names the core package + // exactly as `Aspire.Hosting` does: + // https://learn.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#package-identifiers. + // Nothing downstream is. The substitution probe resolves the name through the + // filesystem, the generated scanner project-references src/Aspire.Hosting under the + // canonical spelling no matter what was asked for, and the exported document records + // this string verbatim as the package identity documentation is keyed on. Settling on + // the canonical spelling here — before the scanner project is created and validated — + // is what keeps the guard, the scanner, and the label describing one package. + var isCorePackage = string.Equals(reference.Name, CorePackageName, StringComparison.OrdinalIgnoreCase); + packageName = isCorePackage ? CorePackageName : reference.Name; + // The core package is always restored by the scanner AppHost, so adding it again would // produce a duplicate package reference. - if (string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase)) + if (isCorePackage) { // The scanner loads the core assemblies this CLI was built against, so a different // requested version would be exported as this CLI's surface under someone else's @@ -258,19 +269,16 @@ private static string StripBuildMetadata(string version) $"Re-run without the override, or export {CorePackageName} from an installed CLI."; } - // The core package is matched case-insensitively but resolved through the filesystem, and - // the generated scanner project-references src/Aspire.Hosting under that exact spelling no - // matter how the caller spelled it. Looking the substitution up under the caller's spelling - // would miss on a case-sensitive filesystem — `--package aspire.hosting` on Linux — and skip - // the whole check while the scanner still built the checkout's core surface. - var lookupName = isCorePackage ? CorePackageName : packageName; - - if (serverProject.GetLocalProjectSubstitution(lookupName) is not { } substitution) + // The name arrives canonical: the caller settles the core package on CorePackageName before + // the scanner project is created, because this lookup resolves through the filesystem and + // would miss `aspire.hosting` on a case-sensitive one while the scanner still built + // src/Aspire.Hosting. + if (serverProject.GetLocalProjectSubstitution(packageName) is not { } substitution) { return null; } - var preamble = $"This CLI runs from an Aspire repository checkout, so {lookupName} is built from {substitution.ProjectPath} " + + var preamble = $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {substitution.ProjectPath} " + $"instead of being restored from a package feed."; if (ExecutionContext.IdentityOverridden) @@ -297,7 +305,7 @@ private static string StripBuildMetadata(string version) return isCorePackage ? $"{preamble} That checkout builds {checkoutPrefix}, but this CLI is {packageVersion}, and exporting it " + $"would describe the checkout's API surface under this CLI's version. " + - $"Export {lookupName} from a {checkoutPrefix} CLI, or point this one at a {StripBuildMetadata(packageVersion)} checkout." + $"Export {packageName} from a {checkoutPrefix} CLI, or point this one at a {StripBuildMetadata(packageVersion)} checkout." : $"{preamble} That checkout builds {checkoutPrefix}, but {packageVersion} was requested, and exporting it " + $"would describe the checkout's API surface under the requested version. " + $"Run the export with the {StripBuildMetadata(packageVersion)} CLI instead."; diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index b283c3bde61..255d5293e60 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -502,10 +502,22 @@ public async Task PrepareAsync( /// /// + /// /// This is the same decision makes, kept in one place so a /// caller asking "will my requested version survive?" cannot drift from what the generated /// project actually does. Only first-party Aspire.Hosting.* packages live under /// src/, so a third-party integration is always restored from a feed even here. + /// + /// + /// The name is matched case-insensitively, because a NuGet package id is + /// () + /// while the filesystem this resolves through is not on Linux. Probing the caller's spelling + /// directly meant aspire.hosting.redis found nothing there and src/Aspire.Hosting.Redis + /// on macOS and Windows, so how a package was spelled decided whether the checkout was used at + /// all — and callers that publish version-keyed artifacts saw no substitution to guard against. + /// The returned path is always the on-disk spelling so the generated project reference and the + /// caller's check name the same project. + /// /// public LocalProjectSubstitution? GetLocalProjectSubstitution(string packageName) { @@ -514,10 +526,33 @@ public async Task PrepareAsync( return null; } - var projectPath = Path.Combine(_repoRoot, "src", packageName, $"{packageName}.csproj"); - return File.Exists(projectPath) - ? new LocalProjectSubstitution(projectPath, GetRepositoryVersionPrefix()) - : null; + var srcPath = Path.Combine(_repoRoot, "src"); + if (!Directory.Exists(srcPath)) + { + return null; + } + + // The directory listing settles the spelling on every platform. Probing + // Path.Combine(src, packageName) instead would hand back the caller's spelling wherever + // File.Exists is case-insensitive, so the same request produced two different project paths + // depending on the filesystem. Enumerate and compare rather than passing the caller's name + // as a search pattern, so a package id that happens to contain a wildcard cannot match a + // directory it does not name. + foreach (var directory in Directory.EnumerateDirectories(srcPath)) + { + var canonicalName = Path.GetFileName(directory); + if (!string.Equals(canonicalName, packageName, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + var projectPath = Path.Combine(directory, $"{canonicalName}.csproj"); + return File.Exists(projectPath) + ? new LocalProjectSubstitution(projectPath, GetRepositoryVersionPrefix()) + : null; + } + + return null; } /// diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index ae626ac759f..611b9f7137c 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -416,6 +416,37 @@ public async Task SdkExportOfTheCorePackageRejectsACheckoutOnAnotherVersionLineW Assert.Empty(interactionService.DisplayedRawText); } + /// + /// Rejecting a bad request under any spelling is half of it. The exported document records the + /// package name verbatim as the identity documentation is keyed on, and the scanner builds + /// src/Aspire.Hosting whatever was typed, so a good request has to be published under the + /// canonical id rather than the caller's spelling. + /// + [Fact] + public async Task SdkExportOfTheCorePackageIsPublishedUnderItsCanonicalNameWhateverTheCasing() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.5.0"); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package aspire.hosting@13.5.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("typescript", "Aspire.Hosting", "13.5.0"), rpcClient.LastExportRequest); + + var stdout = Assert.Single(interactionService.DisplayedRawText, entry => entry.ConsoleOverride == ConsoleOutput.Standard); + using var document = JsonDocument.Parse(stdout.Text); + Assert.Equal("Aspire.Hosting", document.RootElement.GetProperty("package").GetProperty("name").GetString()); + } + /// /// The same checkout on the same version line is exactly what the label claims, so it exports. /// diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs index 447adb7abfc..7f5ddf5f9c4 100644 --- a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs @@ -155,6 +155,69 @@ public void GetLocalProjectSubstitution_ReportsOnlyFirstPartyProjectsThatExist() Assert.Null(project.GetLocalProjectSubstitution("CommunityToolkit.Aspire.Hosting.ActiveMQ")); } + /// + /// A NuGet package id is case-insensitive, but this resolves one through the filesystem, which + /// is not on Linux. Probing the caller's spelling let it decide whether the checkout was + /// substituted at all: aspire.hosting.redis found nothing there while macOS and Windows + /// found src/Aspire.Hosting.Redis, so a caller that publishes version-keyed artifacts saw + /// no substitution to guard against on the one platform the docs pipeline runs on. + /// + [Fact] + public void GetLocalProjectSubstitution_ResolvesFirstPartyProjectsUnderAnyCasing() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + + var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); + File.WriteAllText(redisProjectPath, ""); + + var project = CreateProject(appPath, Path.Combine(appPath, ".aspire_server")); + + // The on-disk spelling, not the caller's. Asserting the canonical path is what makes this + // meaningful on a case-insensitive filesystem too, where probing the caller's spelling + // succeeds but hands back a path spelled the way the request was. + Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("aspire.hosting.redis")?.ProjectPath); + Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("ASPIRE.HOSTING.REDIS")?.ProjectPath); + + // Case-insensitive matching still only reports what the checkout actually contains. + Assert.Null(project.GetLocalProjectSubstitution("aspire.hosting.qdrant")); + } + + /// + /// The substitution check and the generated project have to make the same decision, or a caller + /// that was told nothing would be substituted still gets a scanner built from the checkout. + /// + [Fact] + public async Task CreateProjectFiles_SubstitutesTheCheckoutProjectUnderAnyCasing() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + var projectModelPath = Path.Combine(appPath, ".aspire_server"); + + var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); + File.WriteAllText(redisProjectPath, ""); + + var project = CreateProject(appPath, projectModelPath); + + await project.CreateProjectFilesAsync( + [IntegrationReference.FromExactPackage("aspire.hosting.redis", "13.4.0")]); + + var document = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")); + + Assert.Equal( + [redisProjectPath], + document.Descendants("ProjectReference").Select(element => element.Attribute("Include")!.Value)); + + // No package reference for the integration: the checkout supplies it, which is exactly what + // GetLocalProjectSubstitution reports to callers that publish version-keyed artifacts. The + // two the template always carries are all that is left. + Assert.Equal( + ["StreamJsonRpc", "Google.Protobuf"], + document.Descendants("PackageReference").Select(element => element.Attribute("Include")!.Value)); + } + /// /// The version a checkout builds has to come from the checkout, because the version this CLI /// reports is overrideable. eng/Versions.props is where the repository states it. diff --git a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs index f3106fbad38..1aeabefd6eb 100644 --- a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs +++ b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs @@ -23,11 +23,12 @@ internal sealed class FakeSucceedingAppHostServerProject(string appDirectoryPath /// src/ and the requested package version is discarded. /// /// - /// The comparer is ordinal on purpose. The real implementation resolves a substitution through - /// File.Exists, so it is case-sensitive on Linux and case-insensitive on macOS and - /// Windows. Modelling the strictest platform here means a caller that looks a substitution up - /// under an arbitrary spelling fails everywhere rather than only on the platform CI happens not - /// to be running. + /// The comparer is ordinal on purpose, which is stricter than the real implementation: that one + /// matches a package id case-insensitively the way a feed does. Requiring the canonical spelling + /// here keeps the command's own canonicalization under test rather than resting on the probe, + /// which matters because implementations that report no + /// substitution at all — the prebuilt scanner — leave the command as the only thing that + /// settles the spelling before the export is labelled. /// public Dictionary LocalProjectSubstitutions { get; } = new(StringComparer.Ordinal); From 9f9fccb7326357e2831ef978a31920bb09abd5ee Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 11:59:51 -0400 Subject: [PATCH 21/73] Don't lose the scanner to an unreadable src directory Resolving the substitution by listing src/ trades a File.Exists probe, which cannot throw, for an enumeration that can. CreateProjectFile calls this on the `aspire run` path, so an unreadable or concurrently removed src/ would have taken the whole scanner down rather than reporting that the checkout supplies nothing. It now reports no substitution, which is how GetRepositoryVersionPrefix already treats the same failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../DotNetBasedAppHostServerProject.cs | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index 255d5293e60..1e6e9dfdca6 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -538,18 +538,30 @@ public async Task PrepareAsync( // depending on the filesystem. Enumerate and compare rather than passing the caller's name // as a search pattern, so a package id that happens to contain a wildcard cannot match a // directory it does not name. - foreach (var directory in Directory.EnumerateDirectories(srcPath)) + // + // Enumerating can throw where the old File.Exists probe could not, and this runs on the + // `aspire run` path via CreateProjectFile, so an unreadable or concurrently removed src/ + // reports "no substitution" the same way GetRepositoryVersionPrefix does rather than + // costing the caller its scanner. + try { - var canonicalName = Path.GetFileName(directory); - if (!string.Equals(canonicalName, packageName, StringComparison.OrdinalIgnoreCase)) + foreach (var directory in Directory.EnumerateDirectories(srcPath)) { - continue; - } + var canonicalName = Path.GetFileName(directory); + if (!string.Equals(canonicalName, packageName, StringComparison.OrdinalIgnoreCase)) + { + continue; + } - var projectPath = Path.Combine(directory, $"{canonicalName}.csproj"); - return File.Exists(projectPath) - ? new LocalProjectSubstitution(projectPath, GetRepositoryVersionPrefix()) - : null; + var projectPath = Path.Combine(directory, $"{canonicalName}.csproj"); + return File.Exists(projectPath) + ? new LocalProjectSubstitution(projectPath, GetRepositoryVersionPrefix()) + : null; + } + } + catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) + { + return null; } return null; From a037884cef19d6781daf2b7d90fb808ccfc12d26 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 12:12:46 -0400 Subject: [PATCH 22/73] Publish an export under the package id the assembly carries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Canonicalizing the core name in the CLI fixed the package that is already the default and left the one --package is actually used for. Every other id survived as the caller typed it and reached the document verbatim, so `--package aspire.hosting.redis` published `package.name` as "aspire.hosting.redis" — the identity consumers key on, naming a package nobody looks up. That is the defect just fixed for core, left in place for the general case. The CLI cannot settle this alone: it only knows the on-disk spelling for a first-party package in a checkout, so fixing it there would make the same command emit different documents in repository and prebuilt mode. The server knows in both, because it has the assembly loaded and every filter here already treats a package id as an assembly name. The name is resolved against the loaded assemblies before filtering, so the filter, the options, and the label all use one spelling. A name no assembly carries is echoed back unchanged rather than guessed at; that is a package whose assembly is named differently, and the export filters to nothing either way. Also pin the scanner's package reference to the settled name rather than the parsed one. They agree today because only the core name is rewritten before that point, but they are the same identity and shouldn't be able to drift. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../Commands/Sdk/SdkExportCommand.cs | 4 +- .../AtsContextFilter.cs | 74 +++++++++++++++++++ .../CodeGeneration/CodeGenerationService.cs | 14 +++- .../AtsContextFilterTests.cs | 28 +++++++ 4 files changed, 118 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 5ce8f2dfdea..ac5d869964a 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -151,7 +151,9 @@ protected override async Task ExecuteAsync(ParseResult parseResul { // Pin the requested version: a bare NuGet version is a minimum, so an unavailable // version would restore as a later one and be published under the wrong number. - integrations.Add(IntegrationReference.FromExactPackage(reference.Name, reference.Version)); + // Use packageName rather than reference.Name so the restored reference and the + // exported label can never name the package differently. + integrations.Add(IntegrationReference.FromExactPackage(packageName, reference.Version)); } } diff --git a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs index a5b98774208..a7cbc99717a 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs @@ -11,6 +11,80 @@ namespace Aspire.Hosting.RemoteHost; /// internal static class AtsContextFilter { + /// + /// Returns spelled the way the assembly that carries it is + /// actually named, or unchanged when no loaded assembly matches. + /// + /// + /// A NuGet package id is case-insensitive + /// (), + /// so a caller can name a package in any casing, but an API export records the id verbatim as + /// the identity consumers key on. Every filter here treats the package id as an assembly name, + /// so the loaded assemblies are the authority on how it is spelled. A name that matches nothing + /// is returned unchanged rather than guessed at: that is a package whose assembly is named + /// differently, which the export would already have filtered to nothing. + /// + /// The unfiltered ATS context. + /// The assembly or package name as the caller spelled it. + /// The canonical spelling, or when unmatched. + public static string ResolveCanonicalAssemblyName(AtsContext context, string requestedName) + { + ArgumentNullException.ThrowIfNull(context); + ArgumentException.ThrowIfNullOrWhiteSpace(requestedName); + + foreach (var candidate in EnumerateAssemblyNames(context)) + { + if (string.Equals(candidate, requestedName, StringComparison.OrdinalIgnoreCase)) + { + return candidate; + } + } + + return requestedName; + } + + private static IEnumerable EnumerateAssemblyNames(AtsContext context) + { + foreach (var assemblyName in context.CapabilityExportingAssemblyNames.Values) + { + if (!string.IsNullOrWhiteSpace(assemblyName)) + { + yield return assemblyName; + } + } + + foreach (var type in context.HandleTypes) + { + if (type.ClrType?.Assembly.GetName().Name is { Length: > 0 } name) + { + yield return name; + } + } + + foreach (var type in context.DtoTypes) + { + if (type.ClrType?.Assembly.GetName().Name is { Length: > 0 } name) + { + yield return name; + } + } + + foreach (var type in context.EnumTypes) + { + if (type.ClrType?.Assembly.GetName().Name is { Length: > 0 } name) + { + yield return name; + } + } + + foreach (var exportedValue in context.ExportedValues) + { + if (exportedValue.OwningAssemblyName is { Length: > 0 } name) + { + yield return name; + } + } + } /// /// Filters the given ATS context to include only capabilities and types exported by the specified assemblies. /// diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index 60e078c5352..d48249adaa2 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -314,8 +314,20 @@ public JsonElement ExportApi(string language, string packageName, string package // Referenced handle capabilities determine wrapper and resource-union signatures. // Keep only their projection support shape without publishing their API as part of this // package. + var fullContext = _atsContextFactory.GetContext(); + + // A NuGet package id is case-insensitive + // (https://learn.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#package-identifiers) + // but the exported document records this string verbatim as the identity consumers key + // on, so `aspire.hosting.redis` would publish a document naming a package nobody looks + // up. The loaded assembly settles the spelling: this filter already treats the package + // id as an assembly name, so a package whose API is exportable at all is named here. + // A name with no loaded assembly is left exactly as asked for — that is a package whose + // assembly is named differently, and guessing would be worse than echoing the request. + packageName = AtsContextFilter.ResolveCanonicalAssemblyName(fullContext, packageName); + var context = AtsContextFilter.FilterForApiExport( - _atsContextFactory.GetContext(), + fullContext, [packageName]); var export = exporter.ExportApi(context, new ApiReferenceExportOptions(packageName, packageVersion, [packageName])); diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index 145561acd67..fcdf4f76b34 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -11,6 +11,34 @@ namespace Aspire.Hosting.RemoteHost.Tests; public class AtsContextFilterTests { + /// + /// A NuGet package id is case-insensitive, but an API export records it verbatim as the identity + /// consumers key on, so a document published under the caller's spelling names a package nobody + /// looks up. The loaded assembly is the authority on how it is spelled. + /// + [Fact] + public void ResolveCanonicalAssemblyName_ReturnsTheSpellingTheAssemblyCarries() + { + var context = CreateContext(); + var canonicalName = typeof(AtsContextFilterTests).Assembly.GetName().Name!; + + Assert.Equal(canonicalName, AtsContextFilter.ResolveCanonicalAssemblyName(context, canonicalName.ToLowerInvariant())); + Assert.Equal(canonicalName, AtsContextFilter.ResolveCanonicalAssemblyName(context, canonicalName.ToUpperInvariant())); + Assert.Equal(canonicalName, AtsContextFilter.ResolveCanonicalAssemblyName(context, canonicalName)); + } + + /// + /// A name no loaded assembly carries belongs to a package whose assembly is named differently. + /// Guessing would be worse than echoing the request, and the export filters to nothing either way. + /// + [Fact] + public void ResolveCanonicalAssemblyName_LeavesAnUnmatchedNameAlone() + { + var context = CreateContext(); + + Assert.Equal("contoso.not.loaded", AtsContextFilter.ResolveCanonicalAssemblyName(context, "contoso.not.loaded")); + } + [Fact] public void FilterByExportingAssemblies_StrictFilterKeepsOnlySelectedAssemblyExports() { From a165096dcf0a0d2818f41ba4c605628901160265 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 12:19:37 -0400 Subject: [PATCH 23/73] Canonicalize against the names the filter matches on The resolver gathered assembly names itself and got a narrower set than the filter recognizes. The gap is exactly the case that survives only as the prefix of a capability or type id, which is what's left of a package whose CLR types didn't resolve. The filter matches those through TryGetAssemblyNameFromId and produces a populated context; the resolver saw nothing and echoed the caller's spelling back. So the one input where the "unmatched names filter to nothing anyway" argument doesn't hold was also the one input the resolver silently declined to fix. GetKnownAssemblyNames is already the inventory of what the filter can match on, so use it rather than keeping a second list beside it that can drift. It doesn't gather the capability-exporting names, so seed with those; seeding also puts them ahead of everything else, which is the right precedence because IsCapabilityOwnedBySelectedAssembly consults them first and a recorded exporter that disagrees with a declaring assembly is the spelling that decides ownership. The candidate set is now a superset of every source the filter matches on, so the doc's claim about unmatched names is true rather than merely usually true. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../AtsContextFilter.cs | 66 ++++++------------- .../AtsContextFilterTests.cs | 19 ++++++ 2 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs index a7cbc99717a..a35bbcca3b2 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs @@ -20,9 +20,10 @@ internal static class AtsContextFilter /// (), /// so a caller can name a package in any casing, but an API export records the id verbatim as /// the identity consumers key on. Every filter here treats the package id as an assembly name, - /// so the loaded assemblies are the authority on how it is spelled. A name that matches nothing - /// is returned unchanged rather than guessed at: that is a package whose assembly is named - /// differently, which the export would already have filtered to nothing. + /// so the assemblies this context was scanned from are the authority on how it is spelled. A + /// name that matches nothing is returned unchanged rather than guessed at: the candidates below + /// are a superset of everything + /// can match on, so an unmatched name is one the export would filter to nothing anyway. /// /// The unfiltered ATS context. /// The assembly or package name as the caller spelled it. @@ -32,59 +33,30 @@ public static string ResolveCanonicalAssemblyName(AtsContext context, string req ArgumentNullException.ThrowIfNull(context); ArgumentException.ThrowIfNullOrWhiteSpace(requestedName); - foreach (var candidate in EnumerateAssemblyNames(context)) - { - if (string.Equals(candidate, requestedName, StringComparison.OrdinalIgnoreCase)) - { - return candidate; - } - } + // Seed with the exporting assembly names rather than gathering them afterwards. They are the + // first thing IsCapabilityOwnedBySelectedAssembly consults, so when a capability's recorded + // exporter disagrees with its declaring assembly, the exporter is the spelling that decides + // ownership and must be the one that wins here too. Everything else comes from + // GetKnownAssemblyNames so this cannot drift from the names the filter recognizes -- notably + // the ones parsed out of capability and type ids, which are the only trace of an assembly + // whose CLR types did not resolve. + var candidates = GetKnownAssemblyNames(context, GetExportingAssemblyNames(context)); - return requestedName; + return candidates.TryGetValue(requestedName, out var canonicalName) ? canonicalName : requestedName; } - private static IEnumerable EnumerateAssemblyNames(AtsContext context) + private static HashSet GetExportingAssemblyNames(AtsContext context) { - foreach (var assemblyName in context.CapabilityExportingAssemblyNames.Values) - { - if (!string.IsNullOrWhiteSpace(assemblyName)) - { - yield return assemblyName; - } - } - - foreach (var type in context.HandleTypes) - { - if (type.ClrType?.Assembly.GetName().Name is { Length: > 0 } name) - { - yield return name; - } - } + var exportingAssemblyNames = new HashSet(StringComparer.OrdinalIgnoreCase); - foreach (var type in context.DtoTypes) + foreach (var assemblyName in context.CapabilityExportingAssemblyNames.Values) { - if (type.ClrType?.Assembly.GetName().Name is { Length: > 0 } name) - { - yield return name; - } + AddAssemblyName(exportingAssemblyNames, assemblyName); } - foreach (var type in context.EnumTypes) - { - if (type.ClrType?.Assembly.GetName().Name is { Length: > 0 } name) - { - yield return name; - } - } - - foreach (var exportedValue in context.ExportedValues) - { - if (exportedValue.OwningAssemblyName is { Length: > 0 } name) - { - yield return name; - } - } + return exportingAssemblyNames; } + /// /// Filters the given ATS context to include only capabilities and types exported by the specified assemblies. /// diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index fcdf4f76b34..7463dda1202 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -27,6 +27,25 @@ public void ResolveCanonicalAssemblyName_ReturnsTheSpellingTheAssemblyCarries() Assert.Equal(canonicalName, AtsContextFilter.ResolveCanonicalAssemblyName(context, canonicalName)); } + /// + /// A package whose CLR types did not resolve survives only as the prefix of its capability and + /// type ids, and the filter still matches it there. Canonicalization has to reach the same names + /// the filter does, or that package is the one case that returns a populated document under a + /// name consumers cannot look up. + /// + [Fact] + public void ResolveCanonicalAssemblyName_ReachesAPackageThatSurvivesOnlyInItsIds() + { + var context = CreateContext(); + + Assert.DoesNotContain( + context.HandleTypes, + type => type.AtsTypeId.StartsWith("Aspire.Hosting.Redis/", StringComparison.Ordinal) && type.ClrType is not null); + + Assert.Equal("Aspire.Hosting.Redis", AtsContextFilter.ResolveCanonicalAssemblyName(context, "aspire.hosting.redis")); + Assert.NotEmpty(AtsContextFilter.FilterByExportingAssemblies(context, ["aspire.hosting.redis"]).HandleTypes); + } + /// /// A name no loaded assembly carries belongs to a package whose assembly is named differently. /// Guessing would be worse than echoing the request, and the export filters to nothing either way. From 34f64a334249e40f18719a4642d6d8300a9b1be6 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 12:22:47 -0400 Subject: [PATCH 24/73] Say which type broke the guard, not just that one did Assert.DoesNotContain only proves nothing matched; when the fixture drifts it reports that a predicate found something and leaves you to find out what. Assert.All over the same types names the one whose ClrType stopped being null, which is the whole point of the guard. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../AtsContextFilterTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index 7463dda1202..f74a5835adc 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -38,9 +38,9 @@ public void ResolveCanonicalAssemblyName_ReachesAPackageThatSurvivesOnlyInItsIds { var context = CreateContext(); - Assert.DoesNotContain( - context.HandleTypes, - type => type.AtsTypeId.StartsWith("Aspire.Hosting.Redis/", StringComparison.Ordinal) && type.ClrType is not null); + Assert.All( + context.HandleTypes.Where(type => type.AtsTypeId.StartsWith("Aspire.Hosting.Redis/", StringComparison.Ordinal)), + type => Assert.Null(type.ClrType)); Assert.Equal("Aspire.Hosting.Redis", AtsContextFilter.ResolveCanonicalAssemblyName(context, "aspire.hosting.redis")); Assert.NotEmpty(AtsContextFilter.FilterByExportingAssemblies(context, ["aspire.hosting.redis"]).HandleTypes); From f55f47b482f186e73c6366565bc952c23d49a518 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 13:07:51 -0400 Subject: [PATCH 25/73] Name an export's options interfaces the way the SDK names them Options interfaces are named after the method that produced them, and two packages can expose the same method name with parameters that cannot share one interface. Generation settles that by suffixing the loser, which it can only decide while looking at every package at once. An export projected from a context already filtered to one package never sees the collision, so both packages published RunAsEmulatorOptions with different members. TypeScript merges identical interface declarations, so agreeing fragments were harmless, but disagreeing ones fail to type-check the moment aspire.dev concatenates them -- and neither matched the SDK either way. Azure.EventHubs and Azure.ServiceBus are exactly this: both expose RunAsEmulator with a configureContainer callback over their own emulator resource type. The exporter now takes the manifest it was narrowed from, resolves it first to record the names generation assigns, and reuses them while projecting the filtered context. Names come from the whole picture; declarations stay limited to what the package contributes. While here, stop treating an unmatched package id as a successful export. Canonicalization searches a superset of what the filter matches on, so a name it cannot place is a package that restored but exports nothing under that id -- a package whose assembly is named something other than its package id. That returned an empty document and exit code 0, which reads as "this package has no API" rather than "we looked in the wrong place". Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../AtsTypeScriptCodeGenerator.cs | 5 +- .../TypeScriptApiProjector.cs | 93 ++++++++++---- .../AtsContextFilter.cs | 29 +++-- .../CodeGeneration/CodeGenerationService.cs | 22 +++- .../ApiReferenceExportOptions.cs | 31 ++++- .../AtsTypeScriptCodeGeneratorTests.cs | 113 ++++++++++++++++++ .../AtsContextFilterTests.cs | 41 +++++-- 7 files changed, 283 insertions(+), 51 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index 7dac5819ffa..5463826b3dd 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -452,8 +452,9 @@ public JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions optio // Build the projector from the same context the generator would use, so the exported // documentation describes the exact signatures generation would emit rather than a - // second, independently derived reading of the ATS context. - var projector = new TypeScriptApiProjector(context); + // second, independently derived reading of the ATS context. The manifest goes along for + // the names generation assigns by looking at every package at once. + var projector = new TypeScriptApiProjector(context, options.ManifestContext); var model = projector.BuildApiModel( new TypeScriptApiPackageIdentity(options.PackageName, options.PackageVersion), options.ExportingAssemblyNames); diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 8c8a63ff6cc..4e57159d58a 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -73,6 +73,32 @@ public TypeScriptApiProjector(AtsContext context) _resolved = Resolve(context); } + /// + /// Initializes a projector for an export narrowed out of a larger manifest. + /// + /// The filtered context to project. + /// The unfiltered context was narrowed from. + /// + /// Options interface names are settled by collision across every package at once, so a + /// projection that can only see one package would name them differently than generation does. + /// Resolving the manifest first records the names generation would assign; projecting the + /// filtered context afterwards reuses them, so the fragment carries the SDK's names while still + /// declaring only what this package contributes. See . + /// + public TypeScriptApiProjector(AtsContext context, AtsContext manifestContext) + { + ArgumentNullException.ThrowIfNull(context); + ArgumentNullException.ThrowIfNull(manifestContext); + + var manifestProjector = new TypeScriptApiProjector(manifestContext); + foreach (var (capabilityId, interfaceName) in manifestProjector._capabilityOptionsInterfaceMap) + { + _manifestOptionsInterfaceNames[capabilityId] = interfaceName; + } + + _resolved = Resolve(context); + } + /// Gets the resolved projection of the context this projector was built from. internal TypeScriptResolvedModel Resolved => _resolved; @@ -1116,6 +1142,13 @@ private string GetTypeOwningAssemblyName(string typeId) private readonly Dictionary _capabilityOptionsInterfaceMap = new(StringComparer.Ordinal); + // Options interface names assigned while resolving the unfiltered manifest, keyed by capability + // ID. Populated only for exports narrowed out of a larger context, and deliberately not cleared + // by Resolve: it records a decision made before this projection began, not state derived from + // the context being projected. + + private readonly Dictionary _manifestOptionsInterfaceNames = new(StringComparer.Ordinal); + // Mapping of enum type IDs to TypeScript enum names private readonly Dictionary _enumTypeNames = new(StringComparer.Ordinal); @@ -1656,6 +1689,16 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L return; } + // An export narrowed out of a larger manifest already knows the name generation settled on + // for this capability. Reusing it verbatim is the whole point: rerunning collision + // resolution here would only see this package's methods and could hand two packages the + // same interface name for members that cannot merge. See the two-argument constructor. + if (_manifestOptionsInterfaceNames.TryGetValue(capabilityId, out var manifestInterfaceName)) + { + AssignOptionsInterface(capabilityId, manifestInterfaceName, optionalParams); + return; + } + var baseInterfaceName = GetOptionsInterfaceName(methodName); // Check if an existing interface with this name is compatible @@ -1664,15 +1707,7 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L if (AreOptionsCompatible(existingParams, optionalParams)) { // Compatible - merge any new parameters and share the interface - var existingNames = new HashSet(existingParams.Select(p => p.Name)); - foreach (var param in optionalParams) - { - if (existingNames.Add(param.Name)) - { - existingParams.Add(param); - } - } - _capabilityOptionsInterfaceMap[capabilityId] = baseInterfaceName; + AssignOptionsInterface(capabilityId, baseInterfaceName, optionalParams); return; } @@ -1692,15 +1727,7 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L if (AreOptionsCompatible(suffixedParams, optionalParams)) { // Compatible with this suffixed interface - share it - var existingNames2 = new HashSet(suffixedParams.Select(p => p.Name)); - foreach (var param in optionalParams) - { - if (existingNames2.Add(param.Name)) - { - suffixedParams.Add(param); - } - } - _capabilityOptionsInterfaceMap[capabilityId] = suffixedName; + AssignOptionsInterface(capabilityId, suffixedName, optionalParams); return; } } @@ -1708,12 +1735,36 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L else { // First registration - create the interface - _generatedOptionsInterfaces.Add(baseInterfaceName); - _optionsInterfacesToGenerate[baseInterfaceName] = [.. optionalParams]; - _capabilityOptionsInterfaceMap[capabilityId] = baseInterfaceName; + AssignOptionsInterface(capabilityId, baseInterfaceName, optionalParams); } } + /// + /// Points a capability at a named options interface, creating the interface if this is its first + /// use and otherwise widening it with any parameters it does not already carry. + /// + private void AssignOptionsInterface(string capabilityId, string interfaceName, List optionalParams) + { + if (_optionsInterfacesToGenerate.TryGetValue(interfaceName, out var declaredParams)) + { + var declaredNames = new HashSet(declaredParams.Select(p => p.Name), StringComparer.Ordinal); + foreach (var param in optionalParams) + { + if (declaredNames.Add(param.Name)) + { + declaredParams.Add(param); + } + } + } + else + { + _generatedOptionsInterfaces.Add(interfaceName); + _optionsInterfacesToGenerate[interfaceName] = [.. optionalParams]; + } + + _capabilityOptionsInterfaceMap[capabilityId] = interfaceName; + } + /// /// Checks whether two sets of optional parameters are compatible for sharing an options interface. /// Parameters with the same name must have the same type (including callback parameter types). diff --git a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs index a35bbcca3b2..a126ee9aa77 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Reflection; using Aspire.TypeSystem; @@ -12,23 +13,33 @@ namespace Aspire.Hosting.RemoteHost; internal static class AtsContextFilter { /// - /// Returns spelled the way the assembly that carries it is - /// actually named, or unchanged when no loaded assembly matches. + /// Resolves to the spelling the assembly that carries it + /// actually uses. /// /// + /// /// A NuGet package id is case-insensitive /// (), /// so a caller can name a package in any casing, but an API export records the id verbatim as /// the identity consumers key on. Every filter here treats the package id as an assembly name, - /// so the assemblies this context was scanned from are the authority on how it is spelled. A - /// name that matches nothing is returned unchanged rather than guessed at: the candidates below - /// are a superset of everything - /// can match on, so an unmatched name is one the export would filter to nothing anyway. + /// so the assemblies this context was scanned from are the authority on how it is spelled. + /// + /// + /// Failing to match is worth reporting rather than absorbing. The candidates below are a + /// superset of everything + /// can match on, so a name that matches nothing here is a name the export would filter to + /// nothing — a package that restored but whose assembly is named something else. Continuing + /// under the requested spelling would publish an empty document that claims to describe it. + /// /// /// The unfiltered ATS context. /// The assembly or package name as the caller spelled it. - /// The canonical spelling, or when unmatched. - public static string ResolveCanonicalAssemblyName(AtsContext context, string requestedName) + /// The canonical spelling, when a loaded assembly matches. + /// when a loaded assembly matches; otherwise . + public static bool TryResolveCanonicalAssemblyName( + AtsContext context, + string requestedName, + [NotNullWhen(true)] out string? canonicalName) { ArgumentNullException.ThrowIfNull(context); ArgumentException.ThrowIfNullOrWhiteSpace(requestedName); @@ -42,7 +53,7 @@ public static string ResolveCanonicalAssemblyName(AtsContext context, string req // whose CLR types did not resolve. var candidates = GetKnownAssemblyNames(context, GetExportingAssemblyNames(context)); - return candidates.TryGetValue(requestedName, out var canonicalName) ? canonicalName : requestedName; + return candidates.TryGetValue(requestedName, out canonicalName); } private static HashSet GetExportingAssemblyNames(AtsContext context) diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index d48249adaa2..0923b27a75a 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -320,17 +320,27 @@ public JsonElement ExportApi(string language, string packageName, string package // (https://learn.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#package-identifiers) // but the exported document records this string verbatim as the identity consumers key // on, so `aspire.hosting.redis` would publish a document naming a package nobody looks - // up. The loaded assembly settles the spelling: this filter already treats the package - // id as an assembly name, so a package whose API is exportable at all is named here. - // A name with no loaded assembly is left exactly as asked for — that is a package whose - // assembly is named differently, and guessing would be worse than echoing the request. - packageName = AtsContextFilter.ResolveCanonicalAssemblyName(fullContext, packageName); + // up. The loaded assembly settles the spelling: every filter here treats the package id + // as an assembly name, so a package whose API is exportable at all is named in the + // context. One that is not has nothing to export under that id, and saying so beats + // publishing an empty document that claims to describe it. + if (!AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, packageName, out var canonicalPackageName)) + { + throw new InvalidOperationException( + $"'{packageName}' restored, but the app host loaded no assembly by that name, so there is no API to export under it. " + + "An API export is scoped by assembly name, so this is what a package whose assembly is named something other than " + + "its package id looks like from here."); + } + + packageName = canonicalPackageName; var context = AtsContextFilter.FilterForApiExport( fullContext, [packageName]); - var export = exporter.ExportApi(context, new ApiReferenceExportOptions(packageName, packageVersion, [packageName])); + var export = exporter.ExportApi( + context, + new ApiReferenceExportOptions(packageName, packageVersion, [packageName], fullContext)); _logger.LogDebug("<< exportApi({Language}, {PackageName}) completed in {ElapsedMs}ms", language, packageName, sw.ElapsedMilliseconds); diff --git a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs index ddbcbec9432..b8f9856571c 100644 --- a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs +++ b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs @@ -24,9 +24,14 @@ public sealed class ApiReferenceExportOptions /// The assemblies whose symbols this package owns and documents. Symbols outside this set are /// present only to complete the reference closure. /// + /// + /// The unfiltered context the export was narrowed from, used to reproduce names that generation + /// assigns across the whole manifest rather than per package. + /// /// - /// Thrown when , , or - /// is . + /// Thrown when , , + /// , or is + /// . /// /// /// Thrown when or is empty or @@ -35,15 +40,18 @@ public sealed class ApiReferenceExportOptions public ApiReferenceExportOptions( string packageName, string packageVersion, - IReadOnlyCollection exportingAssemblyNames) + IReadOnlyCollection exportingAssemblyNames, + AtsContext manifestContext) { ArgumentException.ThrowIfNullOrWhiteSpace(packageName); ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); ArgumentNullException.ThrowIfNull(exportingAssemblyNames); + ArgumentNullException.ThrowIfNull(manifestContext); PackageName = packageName; PackageVersion = packageVersion; ExportingAssemblyNames = exportingAssemblyNames; + ManifestContext = manifestContext; } /// @@ -70,4 +78,21 @@ public ApiReferenceExportOptions( /// Gets the assemblies whose symbols this package owns and documents. /// public IReadOnlyCollection ExportingAssemblyNames { get; } + + /// + /// Gets the unfiltered context this export was narrowed from. + /// + /// + /// Most generated names derive from the symbol they describe, so a package filtered out of the + /// context cannot change them. Options interfaces are the exception: they are named after the + /// method that produced them, and two packages can expose the same method name with parameters + /// that cannot share one interface. Generation resolves that by suffixing the loser, which it + /// can only decide while looking at every package at once. An export projected from a filtered + /// context sees no collision, so both packages would publish the same interface name with + /// different members. TypeScript merges identical interface declarations, so agreeing fragments + /// are harmless, but disagreeing ones fail to type-check the moment aspire.dev concatenates + /// them — and neither would have matched the SDK. Keeping the manifest lets the exporter settle + /// those names exactly as generation does before narrowing to what the package documents. + /// + public AtsContext ManifestContext { get; } } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index aba53e55bda..0733cdc202e 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2510,6 +2510,119 @@ public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() Assert.Contains("ContainerResource", declaredNames); } + /// + /// Options interfaces are named after the method that produced them, and generation resolves a + /// collision between two packages by suffixing the loser -- a decision it can only make while + /// looking at every package at once. Projecting a per-package export from its filtered context + /// alone sees no collision, so both packages would publish RunAsEmulatorOptions with + /// members that cannot merge, and aspire.dev concatenates and type-checks those fragments + /// together. Handing the exporter the manifest settles the names the way generation does. + /// + /// + /// Not hypothetical: Aspire.Hosting.Azure.EventHubs and Aspire.Hosting.Azure.ServiceBus + /// both expose RunAsEmulator with a configureContainer callback over their own + /// emulator resource type. + /// + [Fact] + public void ApiExportNamesOptionsInterfacesTheWayFullGenerationDoes() + { + var manifest = CreateEmulatorCollisionContext(); + + var generatedNames = new TypeScriptApiProjector(manifest) + .CapabilityOptionsInterfaceMap + .ToDictionary(entry => entry.Key, entry => entry.Value, StringComparer.Ordinal); + + // Generation must have separated them, or this test is not exercising a collision. + Assert.Equal(2, generatedNames.Values.Distinct(StringComparer.Ordinal).Count()); + + foreach (var packageName in new[] { CollisionPackageA, CollisionPackageB }) + { + var filtered = AtsContextFilter.FilterForApiExport(manifest, [packageName]); + var model = new TypeScriptApiProjector(filtered, manifest).BuildApiModel( + new TypeScriptApiPackageIdentity(packageName, TestPackageVersion), + [packageName]); + + var expectedName = generatedNames[$"{packageName}/runAsEmulator"]; + + Assert.Equal( + [$"{packageName}:options:{expectedName}"], + model.Declarations + .Where(declaration => declaration.Id.Contains(":options:", StringComparison.Ordinal)) + .Select(declaration => declaration.Id) + .Order(StringComparer.Ordinal)); + + Assert.All( + model.Declarations, + declaration => Assert.DoesNotMatch( + $@"\b(?!{Regex.Escape(expectedName)}\b)RunAsEmulator\d*Options\b", + declaration.Content)); + } + } + + private const string CollisionPackageA = "Contoso.Hosting.EventHubs"; + + private const string CollisionPackageB = "Contoso.Hosting.ServiceBus"; + + /// + /// Builds a two-package manifest where both packages expose runAsEmulator with an + /// optional parameter of the same name but an incompatible type, which is what forces + /// generation to suffix one of the two options interfaces. + /// + private static AtsContext CreateEmulatorCollisionContext() + { + static AtsTypeInfo Resource(string packageName, string typeName) => new() + { + AtsTypeId = $"{packageName}/{typeName}", + IsInterface = false, + HasExposeMethods = true, + HasExposeProperties = false, + BaseTypeHierarchy = [], + ImplementedInterfaces = [] + }; + + static AtsCapabilityInfo Emulator(string packageName, AtsTypeInfo target, string optionalTypeId) => new() + { + CapabilityId = $"{packageName}/runAsEmulator", + MethodName = "runAsEmulator", + Parameters = + [ + new AtsParameterInfo + { + Name = "configureContainer", + Type = new AtsTypeRef { TypeId = optionalTypeId, Category = AtsTypeCategory.Primitive }, + IsOptional = true + } + ], + ReturnType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, + TargetTypeId = target.AtsTypeId, + TargetType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, + TargetParameterName = "builder", + ExpandedTargetTypes = [], + ReturnsBuilder = true, + CapabilityKind = AtsCapabilityKind.Method + }; + + var hubsResource = Resource(CollisionPackageA, "EventHubsResource"); + var busResource = Resource(CollisionPackageB, "ServiceBusResource"); + var hubsEmulator = Emulator(CollisionPackageA, hubsResource, AtsConstants.String); + var busEmulator = Emulator(CollisionPackageB, busResource, AtsConstants.Boolean); + + return new AtsContext + { + Capabilities = [hubsEmulator, busEmulator], + HandleTypes = [hubsResource, busResource], + DtoTypes = [], + EnumTypes = [], + ExportedValues = [], + Diagnostics = [], + CapabilityExportingAssemblyNames = new Dictionary(StringComparer.Ordinal) + { + [hubsEmulator.CapabilityId] = CollisionPackageA, + [busEmulator.CapabilityId] = CollisionPackageB + } + }; + } + /// /// Builds the context the canonical exporter sees for a single package: the package's own /// capabilities plus the transitive closure of types they reference from other assemblies. diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index f74a5835adc..17502dbb402 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -16,15 +16,23 @@ public class AtsContextFilterTests /// consumers key on, so a document published under the caller's spelling names a package nobody /// looks up. The loaded assembly is the authority on how it is spelled. /// - [Fact] - public void ResolveCanonicalAssemblyName_ReturnsTheSpellingTheAssemblyCarries() + [Theory] + [InlineData(NameCasing.Lower)] + [InlineData(NameCasing.Upper)] + [InlineData(NameCasing.AsDeclared)] + public void TryResolveCanonicalAssemblyName_ReturnsTheSpellingTheAssemblyCarries(NameCasing casing) { var context = CreateContext(); var canonicalName = typeof(AtsContextFilterTests).Assembly.GetName().Name!; + var requestedName = casing switch + { + NameCasing.Lower => canonicalName.ToLowerInvariant(), + NameCasing.Upper => canonicalName.ToUpperInvariant(), + _ => canonicalName + }; - Assert.Equal(canonicalName, AtsContextFilter.ResolveCanonicalAssemblyName(context, canonicalName.ToLowerInvariant())); - Assert.Equal(canonicalName, AtsContextFilter.ResolveCanonicalAssemblyName(context, canonicalName.ToUpperInvariant())); - Assert.Equal(canonicalName, AtsContextFilter.ResolveCanonicalAssemblyName(context, canonicalName)); + Assert.True(AtsContextFilter.TryResolveCanonicalAssemblyName(context, requestedName, out var resolvedName)); + Assert.Equal(canonicalName, resolvedName); } /// @@ -34,7 +42,7 @@ public void ResolveCanonicalAssemblyName_ReturnsTheSpellingTheAssemblyCarries() /// name consumers cannot look up. /// [Fact] - public void ResolveCanonicalAssemblyName_ReachesAPackageThatSurvivesOnlyInItsIds() + public void TryResolveCanonicalAssemblyName_ReachesAPackageThatSurvivesOnlyInItsIds() { var context = CreateContext(); @@ -42,20 +50,33 @@ public void ResolveCanonicalAssemblyName_ReachesAPackageThatSurvivesOnlyInItsIds context.HandleTypes.Where(type => type.AtsTypeId.StartsWith("Aspire.Hosting.Redis/", StringComparison.Ordinal)), type => Assert.Null(type.ClrType)); - Assert.Equal("Aspire.Hosting.Redis", AtsContextFilter.ResolveCanonicalAssemblyName(context, "aspire.hosting.redis")); + Assert.True(AtsContextFilter.TryResolveCanonicalAssemblyName(context, "aspire.hosting.redis", out var resolvedName)); + Assert.Equal("Aspire.Hosting.Redis", resolvedName); Assert.NotEmpty(AtsContextFilter.FilterByExportingAssemblies(context, ["aspire.hosting.redis"]).HandleTypes); } /// /// A name no loaded assembly carries belongs to a package whose assembly is named differently. - /// Guessing would be worse than echoing the request, and the export filters to nothing either way. + /// The candidates canonicalization searches are a superset of what the filter matches on, so + /// that package exports nothing -- which the caller has to be told rather than left to publish + /// an empty document under a name it never confirmed. /// [Fact] - public void ResolveCanonicalAssemblyName_LeavesAnUnmatchedNameAlone() + public void TryResolveCanonicalAssemblyName_ReportsAnUnmatchedName() { var context = CreateContext(); - Assert.Equal("contoso.not.loaded", AtsContextFilter.ResolveCanonicalAssemblyName(context, "contoso.not.loaded")); + Assert.False(AtsContextFilter.TryResolveCanonicalAssemblyName(context, "contoso.not.loaded", out var resolvedName)); + Assert.Null(resolvedName); + Assert.Empty(AtsContextFilter.FilterByExportingAssemblies(context, ["contoso.not.loaded"]).HandleTypes); + } + + /// Casing variants exercised by . + public enum NameCasing + { + Lower, + Upper, + AsDeclared } [Fact] From d6d6a1bc2ef0dfb132f54124afb0c577df84cfc4 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 13:17:43 -0400 Subject: [PATCH 26/73] Back out a naming fix that cannot fire where it matters The previous commit had the exporter reuse options interface names recorded while resolving "the manifest", on the theory that a per-package export could then name RunAsEmulatorOptions the way full generation does. The manifest it was handed cannot contain the collision. `sdk export` builds a scanner app host referencing exactly the requested package plus the code generation package, so the scanned context is that package, core, and codegen -- never a sibling integration. Azure.EventHubs and Azure.ServiceBus are siblings; neither is in the other's closure, and each export runs in its own app host. Both resolves see one RunAsEmulator, find no collision, and assign the base name, which is exactly the state the previous commit claimed to fix. The test passed only because it fabricated a two-package manifest and handed it to the projector directly, proving the mechanism works while assuming an input the pipeline never produces. Worse, seeding did change one thing: with core in every manifest, an integration colliding with a core method now gets its name decided by scan order, and the core export -- resolved from a core-only manifest -- would not agree. That trades an unreachable fix for a reachable regression. The real constraint is that an options interface name is not a function of the package that owns it. It depends on what else was loaded, so `sdk generate` in two different app hosts already names the same package's interface differently. There is no single "generated SDK" for an export to match. Making names a function of package identity would fix that, but it renames types in emitted TypeScript and belongs in its own change. Keeping the two pieces that stand on their own: the unmatched package id now fails instead of publishing an empty document, and the three copies of the create-or-merge logic in RegisterOptionsInterface are one helper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../AtsTypeScriptCodeGenerator.cs | 5 +- .../TypeScriptApiProjector.cs | 43 ------- .../CodeGeneration/CodeGenerationService.cs | 6 +- .../ApiReferenceExportOptions.cs | 31 +---- .../AtsTypeScriptCodeGeneratorTests.cs | 113 ------------------ 5 files changed, 7 insertions(+), 191 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index 5463826b3dd..7dac5819ffa 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -452,9 +452,8 @@ public JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions optio // Build the projector from the same context the generator would use, so the exported // documentation describes the exact signatures generation would emit rather than a - // second, independently derived reading of the ATS context. The manifest goes along for - // the names generation assigns by looking at every package at once. - var projector = new TypeScriptApiProjector(context, options.ManifestContext); + // second, independently derived reading of the ATS context. + var projector = new TypeScriptApiProjector(context); var model = projector.BuildApiModel( new TypeScriptApiPackageIdentity(options.PackageName, options.PackageVersion), options.ExportingAssemblyNames); diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 4e57159d58a..8de2de6afe9 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -73,32 +73,6 @@ public TypeScriptApiProjector(AtsContext context) _resolved = Resolve(context); } - /// - /// Initializes a projector for an export narrowed out of a larger manifest. - /// - /// The filtered context to project. - /// The unfiltered context was narrowed from. - /// - /// Options interface names are settled by collision across every package at once, so a - /// projection that can only see one package would name them differently than generation does. - /// Resolving the manifest first records the names generation would assign; projecting the - /// filtered context afterwards reuses them, so the fragment carries the SDK's names while still - /// declaring only what this package contributes. See . - /// - public TypeScriptApiProjector(AtsContext context, AtsContext manifestContext) - { - ArgumentNullException.ThrowIfNull(context); - ArgumentNullException.ThrowIfNull(manifestContext); - - var manifestProjector = new TypeScriptApiProjector(manifestContext); - foreach (var (capabilityId, interfaceName) in manifestProjector._capabilityOptionsInterfaceMap) - { - _manifestOptionsInterfaceNames[capabilityId] = interfaceName; - } - - _resolved = Resolve(context); - } - /// Gets the resolved projection of the context this projector was built from. internal TypeScriptResolvedModel Resolved => _resolved; @@ -1142,13 +1116,6 @@ private string GetTypeOwningAssemblyName(string typeId) private readonly Dictionary _capabilityOptionsInterfaceMap = new(StringComparer.Ordinal); - // Options interface names assigned while resolving the unfiltered manifest, keyed by capability - // ID. Populated only for exports narrowed out of a larger context, and deliberately not cleared - // by Resolve: it records a decision made before this projection began, not state derived from - // the context being projected. - - private readonly Dictionary _manifestOptionsInterfaceNames = new(StringComparer.Ordinal); - // Mapping of enum type IDs to TypeScript enum names private readonly Dictionary _enumTypeNames = new(StringComparer.Ordinal); @@ -1689,16 +1656,6 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L return; } - // An export narrowed out of a larger manifest already knows the name generation settled on - // for this capability. Reusing it verbatim is the whole point: rerunning collision - // resolution here would only see this package's methods and could hand two packages the - // same interface name for members that cannot merge. See the two-argument constructor. - if (_manifestOptionsInterfaceNames.TryGetValue(capabilityId, out var manifestInterfaceName)) - { - AssignOptionsInterface(capabilityId, manifestInterfaceName, optionalParams); - return; - } - var baseInterfaceName = GetOptionsInterfaceName(methodName); // Check if an existing interface with this name is compatible diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index 0923b27a75a..b98b7c7a743 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -327,7 +327,7 @@ public JsonElement ExportApi(string language, string packageName, string package if (!AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, packageName, out var canonicalPackageName)) { throw new InvalidOperationException( - $"'{packageName}' restored, but the app host loaded no assembly by that name, so there is no API to export under it. " + + $"'{packageName}' restored, but the scanned API surface contains nothing under that name, so there is no API to export under it. " + "An API export is scoped by assembly name, so this is what a package whose assembly is named something other than " + "its package id looks like from here."); } @@ -338,9 +338,7 @@ public JsonElement ExportApi(string language, string packageName, string package fullContext, [packageName]); - var export = exporter.ExportApi( - context, - new ApiReferenceExportOptions(packageName, packageVersion, [packageName], fullContext)); + var export = exporter.ExportApi(context, new ApiReferenceExportOptions(packageName, packageVersion, [packageName])); _logger.LogDebug("<< exportApi({Language}, {PackageName}) completed in {ElapsedMs}ms", language, packageName, sw.ElapsedMilliseconds); diff --git a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs index b8f9856571c..ddbcbec9432 100644 --- a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs +++ b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs @@ -24,14 +24,9 @@ public sealed class ApiReferenceExportOptions /// The assemblies whose symbols this package owns and documents. Symbols outside this set are /// present only to complete the reference closure. /// - /// - /// The unfiltered context the export was narrowed from, used to reproduce names that generation - /// assigns across the whole manifest rather than per package. - /// /// - /// Thrown when , , - /// , or is - /// . + /// Thrown when , , or + /// is . /// /// /// Thrown when or is empty or @@ -40,18 +35,15 @@ public sealed class ApiReferenceExportOptions public ApiReferenceExportOptions( string packageName, string packageVersion, - IReadOnlyCollection exportingAssemblyNames, - AtsContext manifestContext) + IReadOnlyCollection exportingAssemblyNames) { ArgumentException.ThrowIfNullOrWhiteSpace(packageName); ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); ArgumentNullException.ThrowIfNull(exportingAssemblyNames); - ArgumentNullException.ThrowIfNull(manifestContext); PackageName = packageName; PackageVersion = packageVersion; ExportingAssemblyNames = exportingAssemblyNames; - ManifestContext = manifestContext; } /// @@ -78,21 +70,4 @@ public ApiReferenceExportOptions( /// Gets the assemblies whose symbols this package owns and documents. /// public IReadOnlyCollection ExportingAssemblyNames { get; } - - /// - /// Gets the unfiltered context this export was narrowed from. - /// - /// - /// Most generated names derive from the symbol they describe, so a package filtered out of the - /// context cannot change them. Options interfaces are the exception: they are named after the - /// method that produced them, and two packages can expose the same method name with parameters - /// that cannot share one interface. Generation resolves that by suffixing the loser, which it - /// can only decide while looking at every package at once. An export projected from a filtered - /// context sees no collision, so both packages would publish the same interface name with - /// different members. TypeScript merges identical interface declarations, so agreeing fragments - /// are harmless, but disagreeing ones fail to type-check the moment aspire.dev concatenates - /// them — and neither would have matched the SDK. Keeping the manifest lets the exporter settle - /// those names exactly as generation does before narrowing to what the package documents. - /// - public AtsContext ManifestContext { get; } } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 0733cdc202e..aba53e55bda 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2510,119 +2510,6 @@ public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() Assert.Contains("ContainerResource", declaredNames); } - /// - /// Options interfaces are named after the method that produced them, and generation resolves a - /// collision between two packages by suffixing the loser -- a decision it can only make while - /// looking at every package at once. Projecting a per-package export from its filtered context - /// alone sees no collision, so both packages would publish RunAsEmulatorOptions with - /// members that cannot merge, and aspire.dev concatenates and type-checks those fragments - /// together. Handing the exporter the manifest settles the names the way generation does. - /// - /// - /// Not hypothetical: Aspire.Hosting.Azure.EventHubs and Aspire.Hosting.Azure.ServiceBus - /// both expose RunAsEmulator with a configureContainer callback over their own - /// emulator resource type. - /// - [Fact] - public void ApiExportNamesOptionsInterfacesTheWayFullGenerationDoes() - { - var manifest = CreateEmulatorCollisionContext(); - - var generatedNames = new TypeScriptApiProjector(manifest) - .CapabilityOptionsInterfaceMap - .ToDictionary(entry => entry.Key, entry => entry.Value, StringComparer.Ordinal); - - // Generation must have separated them, or this test is not exercising a collision. - Assert.Equal(2, generatedNames.Values.Distinct(StringComparer.Ordinal).Count()); - - foreach (var packageName in new[] { CollisionPackageA, CollisionPackageB }) - { - var filtered = AtsContextFilter.FilterForApiExport(manifest, [packageName]); - var model = new TypeScriptApiProjector(filtered, manifest).BuildApiModel( - new TypeScriptApiPackageIdentity(packageName, TestPackageVersion), - [packageName]); - - var expectedName = generatedNames[$"{packageName}/runAsEmulator"]; - - Assert.Equal( - [$"{packageName}:options:{expectedName}"], - model.Declarations - .Where(declaration => declaration.Id.Contains(":options:", StringComparison.Ordinal)) - .Select(declaration => declaration.Id) - .Order(StringComparer.Ordinal)); - - Assert.All( - model.Declarations, - declaration => Assert.DoesNotMatch( - $@"\b(?!{Regex.Escape(expectedName)}\b)RunAsEmulator\d*Options\b", - declaration.Content)); - } - } - - private const string CollisionPackageA = "Contoso.Hosting.EventHubs"; - - private const string CollisionPackageB = "Contoso.Hosting.ServiceBus"; - - /// - /// Builds a two-package manifest where both packages expose runAsEmulator with an - /// optional parameter of the same name but an incompatible type, which is what forces - /// generation to suffix one of the two options interfaces. - /// - private static AtsContext CreateEmulatorCollisionContext() - { - static AtsTypeInfo Resource(string packageName, string typeName) => new() - { - AtsTypeId = $"{packageName}/{typeName}", - IsInterface = false, - HasExposeMethods = true, - HasExposeProperties = false, - BaseTypeHierarchy = [], - ImplementedInterfaces = [] - }; - - static AtsCapabilityInfo Emulator(string packageName, AtsTypeInfo target, string optionalTypeId) => new() - { - CapabilityId = $"{packageName}/runAsEmulator", - MethodName = "runAsEmulator", - Parameters = - [ - new AtsParameterInfo - { - Name = "configureContainer", - Type = new AtsTypeRef { TypeId = optionalTypeId, Category = AtsTypeCategory.Primitive }, - IsOptional = true - } - ], - ReturnType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, - TargetTypeId = target.AtsTypeId, - TargetType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, - TargetParameterName = "builder", - ExpandedTargetTypes = [], - ReturnsBuilder = true, - CapabilityKind = AtsCapabilityKind.Method - }; - - var hubsResource = Resource(CollisionPackageA, "EventHubsResource"); - var busResource = Resource(CollisionPackageB, "ServiceBusResource"); - var hubsEmulator = Emulator(CollisionPackageA, hubsResource, AtsConstants.String); - var busEmulator = Emulator(CollisionPackageB, busResource, AtsConstants.Boolean); - - return new AtsContext - { - Capabilities = [hubsEmulator, busEmulator], - HandleTypes = [hubsResource, busResource], - DtoTypes = [], - EnumTypes = [], - ExportedValues = [], - Diagnostics = [], - CapabilityExportingAssemblyNames = new Dictionary(StringComparer.Ordinal) - { - [hubsEmulator.CapabilityId] = CollisionPackageA, - [busEmulator.CapabilityId] = CollisionPackageB - } - }; - } - /// /// Builds the context the canonical exporter sees for a single package: the package's own /// capabilities plus the transitive closure of types they reference from other assemblies. From 1db91e5c1a1f5aaf7951270b7dbcca4b688af6c3 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 14:10:38 -0400 Subject: [PATCH 27/73] Derive TypeScript options interface names from the owning assembly Options interface names were a function of the scan: the first capability to claim a base name kept it, and the next incompatible one walked a counter to RunAsEmulator1Options. Two things fell out of that. Adding an unrelated integration to an app host could rename an interface the user's hand-written TypeScript refers to, because the name a capability got depended on which other packages were present and in what order they were scanned. And `sdk export` runs one app host per package, so Azure.EventHubs and Azure.ServiceBus -- whose runAsEmulator overloads take incompatible callback types -- each projected alone and each emitted RunAsEmulatorOptions. Concatenating those fragments redeclares one interface with conflicting members. Names are now derived from the assembly that exports the capability, so they are a function of the capability alone and a per-package projection agrees with a whole-app-host projection by construction. Aspire.Hosting keeps unqualified names; every other assembly contributes a qualifier (Aspire.Hosting.Azure.EventHubs -> AzureEventHubsRunAsEmulatorOptions). The suffix loop stays as an intra-assembly last resort, where iteration order is the same subsequence in both views. Options interfaces also now go through the same ownership gate as builders, entry points, enums and DTOs, and their declaration fragments are keyed by the owning assembly rather than by the requesting package. Keying by the requester gave one interface a different fragment id in every export that reached it, so concatenation redeclared it instead of deduplicating it. Snapshot churn: 10 of 101 options interfaces in TwoPassScanningGeneratedAspire.verified.ts are renamed, all of them owned by the test fixture assembly. The 91 owned by Aspire.Hosting are unchanged. No app host under playground/ or tests/PolyglotAppHosts/ names an options interface -- they all pass object literals -- so the rename does not reach checked-in TypeScript. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../TypeScriptApiProjector.cs | 197 +++++-- .../AtsTypeScriptCodeGeneratorTests.cs | 194 ++++++- .../Snapshots/AtsGeneratedAspire.verified.ts | 204 +++---- ...eneratorTests.ApiDeclarations.verified.txt | 256 ++++----- ...CodeGeneratorTests.ApiExport.verified.json | 416 +++++++------- ...TwoPassScanningGeneratedAspire.verified.ts | 520 +++++++++--------- .../WithDataVolumeOptionsMerged.verified.ts | 2 +- 7 files changed, 1042 insertions(+), 747 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 8de2de6afe9..3aa2afed778 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -67,6 +67,14 @@ export interface InteractionInputCollectionPromise extends PromiseLike 0 && !TryGetDirectOptionsParameter(optionalParams, out _)) { - RegisterOptionsInterface(cap.CapabilityId, cap.MethodName, optionalParams); + RegisterOptionsInterface(cap.CapabilityId, cap.MethodName, optionalParams, GetCapabilityOwningAssemblyName(context, cap)); } } } @@ -464,14 +473,22 @@ internal TypeScriptApiModel BuildApiModel( } } - // Options interfaces are generated per method name rather than per type, so they are always - // package-owned when the method that produced them is. + // Options interfaces belong to the assembly whose capability produced them, which is what + // both their fragment ID and their documented-item gate key off. Attributing them to the + // requesting package instead would give the same interface a different ID in every export + // that reaches it, so concatenated fragments would redeclare it rather than dedupe, and a + // package would document options interfaces belonging to its dependencies. foreach (var (interfaceName, optionalParams) in _optionsInterfacesToGenerate.OrderBy(kvp => kvp.Key, StringComparer.Ordinal)) { - var (item, declaration) = ProjectOptionsInterface(package, interfaceName, optionalParams); + var owningAssemblyName = _optionsInterfaceOwningAssemblies.GetValueOrDefault(interfaceName, package.Name); + var (item, declaration) = ProjectOptionsInterface(owningAssemblyName, interfaceName, optionalParams); declarations[declaration.Id] = declaration; - items.Add(item); + + if (owned.Contains(item.OwningAssemblyName)) + { + items.Add(item); + } } // Types reached through the referenced-type closure are named by generated unions and @@ -984,7 +1001,7 @@ internal static IReadOnlyList GetClientOnlyDtoProperties( } private (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) ProjectOptionsInterface( - TypeScriptApiPackageIdentity package, + string owningAssemblyName, string interfaceName, List optionalParams) { @@ -996,18 +1013,18 @@ internal static IReadOnlyList GetClientOnlyDtoProperties( Name = param.Name, Declaration = $"{param.Name}?: {MapParameterToTypeScript(param)}", Summary = param.Documentation?.Summary, - OwningAssemblyName = package.Name + OwningAssemblyName = owningAssemblyName }) .ToList(); var item = new TypeScriptApiItem { Id = $"options:{interfaceName}", - TypeId = $"{package.Name}/{interfaceName}", + TypeId = $"{owningAssemblyName}/{interfaceName}", Kind = TypeScriptApiItemKind.Options, Name = interfaceName, Declaration = $"export interface {interfaceName}", - OwningAssemblyName = package.Name, + OwningAssemblyName = owningAssemblyName, Members = members }; @@ -1021,9 +1038,9 @@ internal static IReadOnlyList GetClientOnlyDtoProperties( return (item, new TypeScriptApiDeclaration { - Id = $"{package.Name}:options:{interfaceName}", + Id = $"{owningAssemblyName}:options:{interfaceName}", Content = body.ToString(), - OwningAssemblyName = package.Name + OwningAssemblyName = owningAssemblyName }); } @@ -1064,18 +1081,26 @@ private static string GetOwningAssemblyName(string atsId, string? clrAssemblyNam /// or the exporter would document symbols the filter excluded, or drop symbols it kept. /// private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) + => GetCapabilityOwningAssemblyName(_resolved.Context, capability); + + /// + /// + /// Takes the context explicitly so can attribute capabilities while it is + /// still building the model that _resolved will hold. + /// + private static string GetCapabilityOwningAssemblyName(AtsContext context, AtsCapabilityInfo capability) { - if (_resolved.Context.CapabilityExportingAssemblyNames.TryGetValue(capability.CapabilityId, out var exportingAssemblyName)) + if (context.CapabilityExportingAssemblyNames.TryGetValue(capability.CapabilityId, out var exportingAssemblyName)) { return exportingAssemblyName; } - if (_resolved.Context.Methods.TryGetValue(capability.CapabilityId, out var method)) + if (context.Methods.TryGetValue(capability.CapabilityId, out var method)) { return method.DeclaringType?.Assembly.GetName().Name ?? string.Empty; } - if (_resolved.Context.Properties.TryGetValue(capability.CapabilityId, out var property)) + if (context.Properties.TryGetValue(capability.CapabilityId, out var property)) { return property.DeclaringType?.Assembly.GetName().Name ?? string.Empty; } @@ -1085,7 +1110,7 @@ private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) /// /// Resolves the assembly that owns a handle type, preferring CLR reflection info for the same - /// reason as . + /// reason as . /// private string GetTypeOwningAssemblyName(string typeId) => GetOwningAssemblyName(typeId, _typeRefsById.GetValueOrDefault(typeId)?.ClrType?.Assembly.GetName().Name); @@ -1116,6 +1141,12 @@ private string GetTypeOwningAssemblyName(string typeId) private readonly Dictionary _capabilityOptionsInterfaceMap = new(StringComparer.Ordinal); + // Mapping from options interface name to the assembly that owns it. An interface belongs to the + // assembly whose capability produced it, which is not necessarily the package an export was + // requested for: a scan holds several assemblies, and only some of them are being documented. + + private readonly Dictionary _optionsInterfaceOwningAssemblies = new(StringComparer.Ordinal); + // Mapping of enum type IDs to TypeScript enum names private readonly Dictionary _enumTypeNames = new(StringComparer.Ordinal); @@ -1149,7 +1180,6 @@ private string GetTypeOwningAssemblyName(string typeId) internal static string GetInteractionInputCollectionClassName() => "InteractionInputCollection"; internal const string InputTypeTypeId = "enum:Aspire.Hosting.InputType"; - internal const string InteractionInputTypeId = "Aspire.Hosting/Aspire.Hosting.InteractionInput"; internal const string InteractionInputCollectionTypeId = "Aspire.Hosting/Aspire.Hosting.InteractionInputCollection"; @@ -1563,22 +1593,81 @@ internal static string ToPascalCase(string name) } /// - /// Gets the options interface name for a method. + /// Gets the options interface name for a method owned by . /// Strips any type prefix (e.g., "TypeName.methodName" -> "MethodName"). /// - - internal static string GetOptionsInterfaceName(string methodName) + /// + /// + /// Names are qualified by the owning assembly so that they are a function of the capability + /// alone. Two assemblies can then never derive the same name — which is what lets a per-package + /// API export be projected on its own and still agree with a projection over the whole app host, + /// and what keeps concatenated export fragments from redeclaring one interface with different + /// members. + /// + /// + /// The core hosting package keeps unqualified names. It is present in every scan, so its names + /// were never the ones at risk, and leaving them alone confines the rename to the packages that + /// actually needed it. The qualifier drops a leading Aspire.Hosting. (or Aspire.) + /// and the dots, so Aspire.Hosting.Azure.EventHubs yields + /// AzureEventHubsRunAsEmulatorOptions and Aspire.Hosting.Redis yields + /// RedisWithDataVolumeOptions. + /// + /// + /// Two assemblies whose names differ only by where the dots fall (Aspire.Hosting.Foo.Bar + /// and Aspire.Hosting.FooBar) would collapse to one qualifier. That pair does not exist, + /// and the suffix loop in still keeps the output + /// well-formed if it ever does, so it is not worth a longer name for every package to prevent. + /// + /// + internal static string GetOptionsInterfaceName(string methodName, string owningAssemblyName) { // Strip type prefix if present (e.g., "EndpointReference.getExpression" -> "getExpression") var simpleName = methodName.Contains('.') ? methodName[(methodName.LastIndexOf('.') + 1)..] : methodName; - return $"{ToPascalCase(simpleName)}Options"; + + return $"{GetOptionsInterfaceQualifier(owningAssemblyName)}{ToPascalCase(simpleName)}Options"; + } + + /// + /// Derives the name-space prefix an assembly's options interfaces carry, or an empty string for + /// the core hosting package and for symbols whose owner could not be resolved. + /// + private static string GetOptionsInterfaceQualifier(string owningAssemblyName) + { + if (string.IsNullOrEmpty(owningAssemblyName) || + string.Equals(owningAssemblyName, AtsConstants.AspireHostingAssembly, StringComparison.Ordinal)) + { + return string.Empty; + } + + var remainder = owningAssemblyName; + foreach (var prefix in s_optionsInterfaceQualifierPrefixes) + { + if (remainder.StartsWith(prefix, StringComparison.Ordinal)) + { + remainder = remainder[prefix.Length..]; + break; + } + } + + // Assembly names are dotted identifiers, so dropping the separators is enough to reach a + // legal TypeScript identifier; anything else is defensive against a name that is not. + var qualifier = new StringBuilder(remainder.Length); + foreach (var character in remainder) + { + if (char.IsLetterOrDigit(character)) + { + qualifier.Append(character); + } + } + + return qualifier.Length == 0 ? string.Empty : ToPascalCase(qualifier.ToString()); } /// /// Gets the options interface name for a specific capability, accounting for type conflicts. - /// Falls back to the default method-name-based interface if no specific mapping exists. + /// Falls back to the default name derived from the capability if no specific mapping exists. /// internal string ResolveOptionsInterfaceName(AtsCapabilityInfo capability) @@ -1587,7 +1676,10 @@ internal string ResolveOptionsInterfaceName(AtsCapabilityInfo capability) { return interfaceName; } - return GetOptionsInterfaceName(capability.MethodName); + + // The fallback has to derive the name the same way registration does, or a capability that + // never reached registration would be emitted referring to an interface nothing declares. + return GetOptionsInterfaceName(capability.MethodName, GetCapabilityOwningAssemblyName(capability)); } /// @@ -1643,20 +1735,42 @@ internal static bool TryGetDirectOptionsParameter(List optiona } /// - /// Registers an options interface to be generated later. - /// Uses method name to create the interface name. When methods share a name but have - /// incompatible callback parameter types, separate options interfaces are created with - /// numeric suffixes (e.g., RunAsEmulatorOptions, RunAsEmulator1Options). + /// Registers an options interface to be generated later, under a name derived from the assembly + /// that owns and the method that produced it. /// - - internal void RegisterOptionsInterface(string capabilityId, string methodName, List optionalParams) + /// + /// + /// The name must not depend on which other packages happen to be loaded. The projector runs over + /// whatever an app host references: sdk export scans one integration plus core, while + /// sdk generate scans everything the user's app host pulls in. Naming an interface after + /// its method alone and resolving clashes with a running counter made the result a function of + /// that set, so adding an unrelated integration could rename an interface the user's hand-written + /// TypeScript refers to, and two packages that never meet in one scan could each publish a + /// different RunAsEmulatorOptions — which is TS2717 the moment their API export fragments + /// are concatenated. + /// + /// + /// Qualifying by owning assembly removes both. Every assembly other than the core hosting package + /// gets its own name space, so no two can produce one name, and the name a capability receives is + /// fixed by the capability itself rather than by its company. + /// + /// + /// The capability the interface is being registered for. + /// The method name the interface is derived from. + /// The optional parameters the interface carries. + /// The assembly that exports . + internal void RegisterOptionsInterface( + string capabilityId, + string methodName, + List optionalParams, + string owningAssemblyName) { if (optionalParams.Count == 0) { return; } - var baseInterfaceName = GetOptionsInterfaceName(methodName); + var baseInterfaceName = GetOptionsInterfaceName(methodName, owningAssemblyName); // Check if an existing interface with this name is compatible if (_optionsInterfacesToGenerate.TryGetValue(baseInterfaceName, out var existingParams)) @@ -1664,27 +1778,29 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L if (AreOptionsCompatible(existingParams, optionalParams)) { // Compatible - merge any new parameters and share the interface - AssignOptionsInterface(capabilityId, baseInterfaceName, optionalParams); + AssignOptionsInterface(capabilityId, baseInterfaceName, optionalParams, owningAssemblyName); return; } - // Incompatible - find or create a suffixed interface + // Incompatible - find or create a suffixed interface. Two capabilities can still collide + // here, but only within one assembly: the qualifier already separates the rest. An + // assembly's own capabilities appear in the same relative order whether the context was + // filtered to that package or holds the whole app host, so the suffix each one draws is + // the same in both, which is what keeps a package export agreeing with full generation. for (var suffix = 1; ; suffix++) { - var suffixedName = GetOptionsInterfaceName($"{methodName}{suffix}"); + var suffixedName = GetOptionsInterfaceName($"{methodName}{suffix}", owningAssemblyName); if (!_optionsInterfacesToGenerate.TryGetValue(suffixedName, out var suffixedParams)) { // Create a new interface with this suffix - _generatedOptionsInterfaces.Add(suffixedName); - _optionsInterfacesToGenerate[suffixedName] = [.. optionalParams]; - _capabilityOptionsInterfaceMap[capabilityId] = suffixedName; + AssignOptionsInterface(capabilityId, suffixedName, optionalParams, owningAssemblyName); return; } if (AreOptionsCompatible(suffixedParams, optionalParams)) { // Compatible with this suffixed interface - share it - AssignOptionsInterface(capabilityId, suffixedName, optionalParams); + AssignOptionsInterface(capabilityId, suffixedName, optionalParams, owningAssemblyName); return; } } @@ -1692,7 +1808,7 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L else { // First registration - create the interface - AssignOptionsInterface(capabilityId, baseInterfaceName, optionalParams); + AssignOptionsInterface(capabilityId, baseInterfaceName, optionalParams, owningAssemblyName); } } @@ -1700,7 +1816,11 @@ internal void RegisterOptionsInterface(string capabilityId, string methodName, L /// Points a capability at a named options interface, creating the interface if this is its first /// use and otherwise widening it with any parameters it does not already carry. /// - private void AssignOptionsInterface(string capabilityId, string interfaceName, List optionalParams) + private void AssignOptionsInterface( + string capabilityId, + string interfaceName, + List optionalParams, + string owningAssemblyName) { if (_optionsInterfacesToGenerate.TryGetValue(interfaceName, out var declaredParams)) { @@ -1720,6 +1840,7 @@ private void AssignOptionsInterface(string capabilityId, string interfaceName, L } _capabilityOptionsInterfaceMap[capabilityId] = interfaceName; + _optionsInterfaceOwningAssemblies[interfaceName] = owningAssemblyName; } /// diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index aba53e55bda..ed079ef22eb 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1816,9 +1816,12 @@ public async Task Generate_SameMethodNameOnDifferentTypes_MergesOptionsInterface // only included parameters from whichever overload was registered first. var code = GenerateTwoPassCode(); - // Extract just the WithDataVolumeOptions interface for snapshot verification. - var interfaceStart = code.IndexOf("export interface WithDataVolumeOptions", StringComparison.Ordinal); - Assert.True(interfaceStart >= 0, "WithDataVolumeOptions interface not found in generated code"); + // Extract just the merged options interface for snapshot verification. The fixture's + // withDataVolume overloads are owned by the test assembly, so they merge into that + // assembly's interface rather than into the core one of the same base name. + var interfaceName = $"{TestOptionsPrefix}WithDataVolumeOptions"; + var interfaceStart = code.IndexOf($"export interface {interfaceName}", StringComparison.Ordinal); + Assert.True(interfaceStart >= 0, $"{interfaceName} interface not found in generated code"); var interfaceEnd = code.IndexOf("}", interfaceStart, StringComparison.Ordinal); var interfaceBody = code[interfaceStart..(interfaceEnd + 1)]; @@ -1910,9 +1913,20 @@ public void Scanner_PackageManagerMethods_ExpandToAllJavaScriptResourceTypes(str /// documented symbols; Aspire.Hosting contributes referenced types through the closure. /// private const string TestPackageName = "Aspire.Hosting.CodeGeneration.TypeScript.Tests"; - private const string TestPackageVersion = "13.5.0"; + /// + /// The qualifier the projector derives from for options + /// interfaces it owns. + /// + /// + /// Options interfaces are named after the assembly that exports the capability, so that a + /// package's export names an interface the same way whether it was projected on its own or + /// alongside every other package. Only Aspire.Hosting keeps unqualified names, so the + /// fixture's own interfaces carry this prefix. + /// + private const string TestOptionsPrefix = "CodeGenerationTypeScriptTests"; + [Fact] public async Task ApiExportUsesTheSameResolvedSignaturesAsGeneratedSource() { @@ -2039,29 +2053,29 @@ AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] member => member.Name == "withOptionalString"); Assert.Collection( withOptionalString.Parameters, - parameter => AssertParameter(parameter, "options", "WithOptionalStringOptions", isOptional: true)); + parameter => AssertParameter(parameter, "options", $"{TestOptionsPrefix}WithOptionalStringOptions", isOptional: true)); var withOptionsCollision = Assert.Single( testRedisResource.Members, member => member.Name == "withOptionsCollision"); Assert.Equal( - "withOptionsCollision(options: string, optionsBag: string, _optionsBag?: WithOptionsCollisionOptions): Promise", + $"withOptionsCollision(options: string, optionsBag: string, _optionsBag?: {TestOptionsPrefix}WithOptionsCollisionOptions): Promise", withOptionsCollision.Declaration); Assert.Collection( withOptionsCollision.Parameters, parameter => AssertParameter(parameter, "options", "string", isOptional: false, "Required options value."), parameter => AssertParameter(parameter, "optionsBag", "string", isOptional: false, "Required options bag value."), - parameter => AssertParameter(parameter, "_optionsBag", "WithOptionsCollisionOptions", isOptional: true)); + parameter => AssertParameter(parameter, "_optionsBag", $"{TestOptionsPrefix}WithOptionsCollisionOptions", isOptional: true)); var withOptionalOptionsField = Assert.Single( testRedisResource.Members, member => member.Name == "withOptionalOptionsField"); Assert.Equal( - "withOptionalOptionsField(options?: WithOptionalOptionsFieldOptions): Promise", + $"withOptionalOptionsField(options?: {TestOptionsPrefix}WithOptionalOptionsFieldOptions): Promise", withOptionalOptionsField.Declaration); Assert.Collection( withOptionalOptionsField.Parameters, - parameter => AssertParameter(parameter, "options", "WithOptionalOptionsFieldOptions", isOptional: true)); + parameter => AssertParameter(parameter, "options", $"{TestOptionsPrefix}WithOptionalOptionsFieldOptions", isOptional: true)); var withDirectOptionsAndCancellation = Assert.Single( testRedisResource.Members, @@ -2083,7 +2097,7 @@ AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] Assert.Contains(withOptionalOptionsField.Declaration, testRedisResourceMembers); Assert.Contains(withDirectOptionsAndCancellation.Declaration, testRedisResourceMembers); Assert.Contains( - "async withOptionalOptionsField(optionsBag?: WithOptionalOptionsFieldOptions): Promise {", + $$"""async withOptionalOptionsField(optionsBag?: {{TestOptionsPrefix}}WithOptionalOptionsFieldOptions): Promise {""", generatedSource); Assert.Contains("const options = optionsBag?.options;", generatedSource); Assert.DoesNotContain("const options = options?.options;", generatedSource); @@ -2510,6 +2524,166 @@ public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() Assert.Contains("ContainerResource", declaredNames); } + /// + /// Two packages that expose the same capability name with incompatible parameter types must + /// name their options interfaces the same way whether they are scanned together or apart. + /// + /// + /// sdk export runs one app host per package, so the projector only ever sees the + /// requested package plus core, while sdk generate sees whatever the user's app host + /// references. Deriving the name from the exporting assembly is what makes those two views + /// agree: naming by method alone gave both packages RunAsEmulatorOptions when projected + /// apart, which is a duplicate declaration with conflicting members once aspire.dev + /// concatenates their fragments. + /// + [Fact] + public void OptionsInterfaceNamesDoNotDependOnWhichOtherPackagesWereScanned() + { + var scannedTogether = new TypeScriptApiProjector(CreateEmulatorCollisionContext()); + var hubsAlone = new TypeScriptApiProjector(CreateEmulatorCollisionContext(includeServiceBus: false)); + var busAlone = new TypeScriptApiProjector(CreateEmulatorCollisionContext(includeEventHubs: false)); + + static string EmulatorInterfaceName(TypeScriptApiProjector projector, string packageName) + => projector.ResolveOptionsInterfaceName( + projector.Resolved.Context.Capabilities.Single(c => c.CapabilityId == $"{packageName}/runAsEmulator")); + + Assert.Equal("AzureEventHubsRunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); + Assert.Equal("AzureServiceBusRunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); + + Assert.Equal( + EmulatorInterfaceName(hubsAlone, CollisionPackageA), + EmulatorInterfaceName(scannedTogether, CollisionPackageA)); + Assert.Equal( + EmulatorInterfaceName(busAlone, CollisionPackageB), + EmulatorInterfaceName(scannedTogether, CollisionPackageB)); + } + + /// + /// An options interface is documented by, and keyed to, the assembly whose capability produced + /// it rather than the package the export was requested for. + /// + /// + /// The projector's context reaches beyond the requested package, so an unscoped emission would + /// let one package publish its dependencies' options interfaces under its own version. Keying + /// the declaration by the requesting package instead of the owner is the same bug from the + /// other side: the same interface would carry a different fragment id in every export that + /// reached it, so concatenation would redeclare it rather than deduplicate it. + /// + [Fact] + public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() + { + var projector = new TypeScriptApiProjector(CreateEmulatorCollisionContext()); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(CollisionPackageA, TestPackageVersion), + [CollisionPackageA]); + + var documentedOptions = model.Modules + .SelectMany(module => module.Items) + .Where(item => item.Kind == TypeScriptApiItemKind.Options) + .ToList(); + + Assert.Collection( + documentedOptions, + item => + { + Assert.Equal("AzureEventHubsRunAsEmulatorOptions", item.Name); + Assert.Equal(CollisionPackageA, item.OwningAssemblyName); + }); + + var serviceBusDeclaration = Assert.Single( + model.Declarations, + declaration => declaration.Content.Contains("AzureServiceBusRunAsEmulatorOptions", StringComparison.Ordinal)); + + Assert.Equal($"{CollisionPackageB}:options:AzureServiceBusRunAsEmulatorOptions", serviceBusDeclaration.Id); + Assert.Equal(CollisionPackageB, serviceBusDeclaration.OwningAssemblyName); + } + + private const string CollisionPackageA = "Aspire.Hosting.Azure.EventHubs"; + private const string CollisionPackageB = "Aspire.Hosting.Azure.ServiceBus"; + + /// + /// Builds a manifest where both packages expose runAsEmulator with an optional parameter + /// of the same name but an incompatible type, which is what forced generation to suffix one of + /// the two options interfaces when names were derived from the method alone. + /// + /// + /// The two package names are the real ones: AzureEventHubsExtensions.RunAsEmulator and + /// AzureServiceBusExtensions.RunAsEmulator both take an optional + /// Action<IResourceBuilder<T>> for different T, so their options + /// interfaces cannot be merged. The capabilities here are synthetic; only the shape matters. + /// + private static AtsContext CreateEmulatorCollisionContext(bool includeEventHubs = true, bool includeServiceBus = true) + { + static AtsTypeInfo Resource(string packageName, string typeName) => new() + { + AtsTypeId = $"{packageName}/{typeName}", + IsInterface = false, + HasExposeMethods = true, + HasExposeProperties = false, + BaseTypeHierarchy = [], + ImplementedInterfaces = [] + }; + + static AtsCapabilityInfo Emulator(string packageName, AtsTypeInfo target, string optionalTypeId) => new() + { + CapabilityId = $"{packageName}/runAsEmulator", + MethodName = "runAsEmulator", + Parameters = + [ + new AtsParameterInfo + { + Name = "configureContainer", + Type = new AtsTypeRef { TypeId = optionalTypeId, Category = AtsTypeCategory.Primitive }, + IsOptional = true + } + ], + ReturnType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, + TargetTypeId = target.AtsTypeId, + TargetType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, + TargetParameterName = "builder", + ExpandedTargetTypes = [], + ReturnsBuilder = true, + CapabilityKind = AtsCapabilityKind.Method + }; + + var hubsResource = Resource(CollisionPackageA, "EventHubsResource"); + var busResource = Resource(CollisionPackageB, "ServiceBusResource"); + + // The two differ in the type of their shared optional parameter, so the interfaces are not + // mergeable and one of them had to be renamed to make room for the other. + var hubsEmulator = Emulator(CollisionPackageA, hubsResource, AtsConstants.String); + var busEmulator = Emulator(CollisionPackageB, busResource, AtsConstants.Boolean); + + List capabilities = []; + List handleTypes = []; + var exportingAssemblyNames = new Dictionary(StringComparer.Ordinal); + + if (includeEventHubs) + { + capabilities.Add(hubsEmulator); + handleTypes.Add(hubsResource); + exportingAssemblyNames[hubsEmulator.CapabilityId] = CollisionPackageA; + } + + if (includeServiceBus) + { + capabilities.Add(busEmulator); + handleTypes.Add(busResource); + exportingAssemblyNames[busEmulator.CapabilityId] = CollisionPackageB; + } + + return new AtsContext + { + Capabilities = capabilities, + HandleTypes = handleTypes, + DtoTypes = [], + EnumTypes = [], + ExportedValues = [], + Diagnostics = [], + CapabilityExportingAssemblyNames = exportingAssemblyNames + }; + } + /// /// Builds the context the canonical exporter sees for a single package: the package's own /// capabilities plus the transitive closure of types they reference from other assemblies. diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts index 1032ac8f00a..20a8714cea9 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts @@ -172,47 +172,47 @@ export namespace TestConfigs { // Options Interfaces // ============================================================================ -export interface AddTestChildDatabaseOptions { +export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions { databaseName?: string; } -export interface AddTestRedisOptions { +export interface CodeGenerationTypeScriptTestsAddTestRedisOptions { port?: number; } -export interface GetStatusAsyncOptions { +export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface WaitForReadyAsyncOptions { +export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface WithDataVolumeOptions { +export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface WithMergeLoggingOptions { +export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -export interface WithMergeLoggingPathOptions { +export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -export interface WithOptionalCallbackOptions { +export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -export interface WithOptionalStringOptions { +export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -export interface WithPersistenceOptions { +export interface CodeGenerationTypeScriptTestsWithPersistenceOptions { mode?: TestPersistenceMode; } @@ -667,7 +667,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -679,7 +679,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addTestRedis(name, options)), this._client); } @@ -769,7 +769,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -784,7 +784,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -807,7 +807,7 @@ export interface TestDatabaseResource { * Adds a data volume * @param options Additional options. */ - withDataVolume(options?: WithDataVolumeOptions): TestDatabaseResourcePromise; + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestDatabaseResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestDatabaseResourcePromise; /** Adds a categorized label to the resource */ @@ -820,12 +820,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -837,7 +837,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withOptionalString(options)), this._client); } @@ -1380,7 +1380,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -1420,7 +1420,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - withDataVolume(options?: WithDataVolumeOptions): TestDatabaseResourcePromise { + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -1440,11 +1440,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -1471,17 +1471,17 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1502,7 +1502,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1529,21 +1529,21 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: GetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1556,12 +1556,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1576,17 +1576,17 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1607,7 +1607,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1634,21 +1634,21 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: GetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1661,12 +1661,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1700,7 +1700,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -1720,7 +1720,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -1741,7 +1741,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -1880,7 +1880,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2056,7 +2056,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: GetStatusAsyncOptions): Promise { + async getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2089,7 +2089,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2137,7 +2137,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -2219,7 +2219,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2241,7 +2241,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -2296,15 +2296,15 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return this._promise.then(onfulfilled, onrejected); } - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -2340,7 +2340,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -2388,7 +2388,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: GetStatusAsyncOptions): Promise { + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -2396,7 +2396,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -2404,7 +2404,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -2424,11 +2424,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -2452,7 +2452,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2467,7 +2467,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2500,12 +2500,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2517,7 +2517,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2532,7 +2532,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2565,12 +2565,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2602,7 +2602,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -2708,7 +2708,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2951,7 +2951,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2973,7 +2973,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3028,7 +3028,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3052,7 +3052,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3112,11 +3112,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -3140,7 +3140,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3153,7 +3153,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3182,12 +3182,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3199,7 +3199,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3212,7 +3212,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3241,12 +3241,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3278,7 +3278,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -3364,7 +3364,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -3577,7 +3577,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -3599,7 +3599,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3654,7 +3654,7 @@ class ResourcePromiseImpl implements ResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3674,7 +3674,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3726,11 +3726,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index 7016f39b689..aae67a2f3a7 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -1,12 +1,12 @@ // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource export interface CSharpAppResource { - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -20,21 +20,21 @@ export interface CSharpAppResource { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise export interface CSharpAppResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -48,20 +48,20 @@ export interface CSharpAppResourcePromise { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource export interface ContainerRegistryResource { - withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -74,20 +74,20 @@ export interface ContainerRegistryResource { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise export interface ContainerRegistryResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -100,21 +100,21 @@ export interface ContainerRegistryResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource export interface ContainerResource { - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -128,21 +128,21 @@ export interface ContainerResource { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise export interface ContainerResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -156,33 +156,33 @@ export interface ContainerResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder export interface DistributedApplicationBuilder { - addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise export interface DistributedApplicationBuilderPromise { - addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource export interface DotnetToolResource { - withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -196,21 +196,21 @@ export interface DotnetToolResource { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise export interface DotnetToolResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -224,21 +224,21 @@ export interface DotnetToolResourcePromise { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource export interface ExecutableResource { - withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -252,21 +252,21 @@ export interface ExecutableResource { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise export interface ExecutableResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -280,20 +280,20 @@ export interface ExecutableResourcePromise { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource export interface ExternalServiceResource { - withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -306,20 +306,20 @@ export interface ExternalServiceResource { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise export interface ExternalServiceResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -332,20 +332,20 @@ export interface ExternalServiceResourcePromise { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource export interface ParameterResource { - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -358,20 +358,20 @@ export interface ParameterResource { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise export interface ParameterResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -384,21 +384,21 @@ export interface ParameterResourcePromise { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource export interface ProjectResource { - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -412,21 +412,21 @@ export interface ProjectResource { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise export interface ProjectResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -440,20 +440,20 @@ export interface ProjectResourcePromise { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource export interface Resource { - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -466,20 +466,20 @@ export interface Resource { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise export interface ResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -492,8 +492,8 @@ export interface ResourcePromise { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } @@ -586,13 +586,13 @@ export interface TestCollectionContextPromise extends PromiseLike Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -606,21 +606,21 @@ export interface TestDatabaseResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise export interface TestDatabaseResourcePromise extends PromiseLike { - withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise; withConfig(config: TestConfigDto): TestDatabaseResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -634,8 +634,8 @@ export interface TestDatabaseResourcePromise extends PromiseLike>; getMetadata(): Promise>; @@ -669,7 +669,7 @@ export interface TestRedisResource extends ResourceBuilderBase { withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -681,26 +681,26 @@ export interface TestRedisResource extends ResourceBuilderBase { withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: GetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise export interface TestRedisResourcePromise extends PromiseLike { - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; withConfig(config: TestConfigDto): TestRedisResourcePromise; getTags(): Promise>; getMetadata(): Promise>; @@ -709,7 +709,7 @@ export interface TestRedisResourcePromise extends PromiseLike withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -721,17 +721,17 @@ export interface TestRedisResourcePromise extends PromiseLike withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: GetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } @@ -758,13 +758,13 @@ export interface TestResourceContextPromise extends PromiseLike Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -779,21 +779,21 @@ export interface TestVaultResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise export interface TestVaultResourcePromise extends PromiseLike { - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; withConfig(config: TestConfigDto): TestVaultResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -808,63 +808,63 @@ export interface TestVaultResourcePromise extends PromiseLike withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions -export interface AddTestChildDatabaseOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions +export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions { databaseName?: string; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions -export interface AddTestRedisOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestRedisOptions +export interface CodeGenerationTypeScriptTestsAddTestRedisOptions { port?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions -export interface GetStatusAsyncOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsGetStatusAsyncOptions +export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions -export interface WaitForReadyAsyncOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions +export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithDataVolumeOptions -export interface WithDataVolumeOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithDataVolumeOptions +export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions -export interface WithMergeLoggingOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingOptions +export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions -export interface WithMergeLoggingPathOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions +export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions -export interface WithOptionalCallbackOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions +export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions -export interface WithOptionalStringOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalStringOptions +export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithPersistenceOptions -export interface WithPersistenceOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithPersistenceOptions +export interface CodeGenerationTypeScriptTestsWithPersistenceOptions { mode?: TestPersistenceMode; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index eb41cd410c3..97a3f422e94 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -24,14 +24,14 @@ "id": "method:CSharpAppResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "CSharpAppResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -120,14 +120,14 @@ "id": "method:CSharpAppResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "CSharpAppResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -364,7 +364,7 @@ "id": "method:CSharpAppResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging", @@ -376,7 +376,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -385,7 +385,7 @@ "id": "method:CSharpAppResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging with file path", @@ -402,7 +402,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -491,14 +491,14 @@ "id": "method:ContainerRegistryResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerRegistryResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -571,14 +571,14 @@ "id": "method:ContainerRegistryResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -799,7 +799,7 @@ "id": "method:ContainerRegistryResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging", @@ -811,7 +811,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -820,7 +820,7 @@ "id": "method:ContainerRegistryResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging with file path", @@ -837,7 +837,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -927,14 +927,14 @@ "id": "method:ContainerResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -1023,14 +1023,14 @@ "id": "method:ContainerResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -1267,7 +1267,7 @@ "id": "method:ContainerResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging", @@ -1279,7 +1279,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -1288,7 +1288,7 @@ "id": "method:ContainerResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging with file path", @@ -1305,7 +1305,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -1392,7 +1392,7 @@ "id": "method:DistributedApplicationBuilder.addTestRedis", "kind": "method", "name": "addTestRedis", - "declaration": "addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise", + "declaration": "addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestRedis", "returnType": "TestRedisResourcePromise", "summary": "Adds a test Redis resource from ATS documentation.", @@ -1405,7 +1405,7 @@ }, { "name": "options", - "type": "AddTestRedisOptions", + "type": "CodeGenerationTypeScriptTestsAddTestRedisOptions", "optional": true } ] @@ -1443,14 +1443,14 @@ "id": "method:DotnetToolResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "DotnetToolResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -1539,14 +1539,14 @@ "id": "method:DotnetToolResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "DotnetToolResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -1783,7 +1783,7 @@ "id": "method:DotnetToolResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging", @@ -1795,7 +1795,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -1804,7 +1804,7 @@ "id": "method:DotnetToolResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging with file path", @@ -1821,7 +1821,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -1912,14 +1912,14 @@ "id": "method:ExecutableResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExecutableResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -2008,14 +2008,14 @@ "id": "method:ExecutableResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExecutableResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -2252,7 +2252,7 @@ "id": "method:ExecutableResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging", @@ -2264,7 +2264,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -2273,7 +2273,7 @@ "id": "method:ExecutableResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging with file path", @@ -2290,7 +2290,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -2379,14 +2379,14 @@ "id": "method:ExternalServiceResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExternalServiceResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -2459,14 +2459,14 @@ "id": "method:ExternalServiceResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExternalServiceResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -2687,7 +2687,7 @@ "id": "method:ExternalServiceResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging", @@ -2699,7 +2699,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -2708,7 +2708,7 @@ "id": "method:ExternalServiceResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging with file path", @@ -2725,7 +2725,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -2815,14 +2815,14 @@ "id": "method:ParameterResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ParameterResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -2895,14 +2895,14 @@ "id": "method:ParameterResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ParameterResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -3123,7 +3123,7 @@ "id": "method:ParameterResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging", @@ -3135,7 +3135,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -3144,7 +3144,7 @@ "id": "method:ParameterResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging with file path", @@ -3161,7 +3161,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -3251,14 +3251,14 @@ "id": "method:ProjectResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ProjectResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -3347,14 +3347,14 @@ "id": "method:ProjectResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ProjectResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -3591,7 +3591,7 @@ "id": "method:ProjectResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging", @@ -3603,7 +3603,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -3612,7 +3612,7 @@ "id": "method:ProjectResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging with file path", @@ -3629,7 +3629,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -3719,14 +3719,14 @@ "id": "method:Resource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -3799,14 +3799,14 @@ "id": "method:Resource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -4027,7 +4027,7 @@ "id": "method:Resource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ResourcePromise", "summary": "Configures resource logging", @@ -4039,7 +4039,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -4048,7 +4048,7 @@ "id": "method:Resource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ResourcePromise", "summary": "Configures resource logging with file path", @@ -4065,7 +4065,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -4473,14 +4473,14 @@ "id": "method:TestDatabaseResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestDatabaseResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -4569,14 +4569,14 @@ "id": "method:TestDatabaseResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestDatabaseResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -4813,7 +4813,7 @@ "id": "method:TestDatabaseResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging", @@ -4825,7 +4825,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -4834,7 +4834,7 @@ "id": "method:TestDatabaseResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging with file path", @@ -4851,7 +4851,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -4996,7 +4996,7 @@ "id": "method:TestRedisResource.addTestChildDatabase", "kind": "method", "name": "addTestChildDatabase", - "declaration": "addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise", + "declaration": "addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestChildDatabase", "returnType": "TestDatabaseResourcePromise", "summary": "Adds a child database to a test Redis resource", @@ -5009,7 +5009,7 @@ }, { "name": "options", - "type": "AddTestChildDatabaseOptions", + "type": "CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", "optional": true } ] @@ -5018,14 +5018,14 @@ "id": "method:TestRedisResource.withPersistence", "kind": "method", "name": "withPersistence", - "declaration": "withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise", + "declaration": "withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withPersistence", "returnType": "TestRedisResourcePromise", "summary": "Configures the Redis resource with persistence", "parameters": [ { "name": "options", - "type": "WithPersistenceOptions", + "type": "CodeGenerationTypeScriptTestsWithPersistenceOptions", "optional": true } ] @@ -5034,14 +5034,14 @@ "id": "method:TestRedisResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestRedisResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -5164,14 +5164,14 @@ "id": "method:TestRedisResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestRedisResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -5349,14 +5349,14 @@ "id": "method:TestRedisResource.getStatusAsync", "kind": "method", "name": "getStatusAsync", - "declaration": "getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E", + "declaration": "getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise\u003Cstring\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getStatusAsync", "returnType": "Promise\u003Cstring\u003E", "summary": "Gets the status of the resource asynchronously", "parameters": [ { "name": "options", - "type": "GetStatusAsyncOptions", + "type": "CodeGenerationTypeScriptTestsGetStatusAsyncOptions", "optional": true } ] @@ -5381,7 +5381,7 @@ "id": "method:TestRedisResource.waitForReadyAsync", "kind": "method", "name": "waitForReadyAsync", - "declaration": "waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", + "declaration": "waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync", "returnType": "Promise\u003Cboolean\u003E", "summary": "Waits for the resource to be ready", @@ -5393,7 +5393,7 @@ }, { "name": "options", - "type": "WaitForReadyAsyncOptions", + "type": "CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", "optional": true } ] @@ -5418,14 +5418,14 @@ "id": "method:TestRedisResource.withDataVolume", "kind": "method", "name": "withDataVolume", - "declaration": "withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise", + "declaration": "withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDataVolume", "returnType": "TestRedisResourcePromise", "summary": "Adds a data volume with persistence", "parameters": [ { "name": "options", - "type": "WithDataVolumeOptions", + "type": "CodeGenerationTypeScriptTestsWithDataVolumeOptions", "optional": true } ] @@ -5518,7 +5518,7 @@ "id": "method:TestRedisResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging", @@ -5530,7 +5530,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -5539,7 +5539,7 @@ "id": "method:TestRedisResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging with file path", @@ -5556,7 +5556,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -5704,14 +5704,14 @@ "id": "method:TestVaultResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise", + "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestVaultResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "WithOptionalStringOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", "optional": true } ] @@ -5800,14 +5800,14 @@ "id": "method:TestVaultResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestVaultResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "WithOptionalCallbackOptions", + "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "optional": true } ] @@ -6060,7 +6060,7 @@ "id": "method:TestVaultResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging", @@ -6072,7 +6072,7 @@ }, { "name": "options", - "type": "WithMergeLoggingOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "optional": true } ] @@ -6081,7 +6081,7 @@ "id": "method:TestVaultResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging with file path", @@ -6098,7 +6098,7 @@ }, { "name": "options", - "type": "WithMergeLoggingPathOptions", + "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "optional": true } ] @@ -6173,15 +6173,15 @@ ] }, { - "id": "options:AddTestChildDatabaseOptions", + "id": "options:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", "kind": "options", - "name": "AddTestChildDatabaseOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestChildDatabaseOptions", + "name": "CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface AddTestChildDatabaseOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", "members": [ { - "id": "property:AddTestChildDatabaseOptions.databaseName", + "id": "property:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions.databaseName", "kind": "property", "name": "databaseName", "declaration": "databaseName?: string" @@ -6189,15 +6189,15 @@ ] }, { - "id": "options:AddTestRedisOptions", + "id": "options:CodeGenerationTypeScriptTestsAddTestRedisOptions", "kind": "options", - "name": "AddTestRedisOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestRedisOptions", + "name": "CodeGenerationTypeScriptTestsAddTestRedisOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsAddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface AddTestRedisOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsAddTestRedisOptions", "members": [ { - "id": "property:AddTestRedisOptions.port", + "id": "property:CodeGenerationTypeScriptTestsAddTestRedisOptions.port", "kind": "property", "name": "port", "declaration": "port?: number" @@ -6205,15 +6205,15 @@ ] }, { - "id": "options:GetStatusAsyncOptions", + "id": "options:CodeGenerationTypeScriptTestsGetStatusAsyncOptions", "kind": "options", - "name": "GetStatusAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/GetStatusAsyncOptions", + "name": "CodeGenerationTypeScriptTestsGetStatusAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsGetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface GetStatusAsyncOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions", "members": [ { - "id": "property:GetStatusAsyncOptions.cancellationToken", + "id": "property:CodeGenerationTypeScriptTestsGetStatusAsyncOptions.cancellationToken", "kind": "property", "name": "cancellationToken", "declaration": "cancellationToken?: AbortSignal | CancellationToken" @@ -6221,15 +6221,15 @@ ] }, { - "id": "options:WaitForReadyAsyncOptions", + "id": "options:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", "kind": "options", - "name": "WaitForReadyAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WaitForReadyAsyncOptions", + "name": "CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WaitForReadyAsyncOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", "members": [ { - "id": "property:WaitForReadyAsyncOptions.cancellationToken", + "id": "property:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions.cancellationToken", "kind": "property", "name": "cancellationToken", "declaration": "cancellationToken?: AbortSignal | CancellationToken" @@ -6237,21 +6237,21 @@ ] }, { - "id": "options:WithDataVolumeOptions", + "id": "options:CodeGenerationTypeScriptTestsWithDataVolumeOptions", "kind": "options", - "name": "WithDataVolumeOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithDataVolumeOptions", + "name": "CodeGenerationTypeScriptTestsWithDataVolumeOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithDataVolumeOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions", "members": [ { - "id": "property:WithDataVolumeOptions.name", + "id": "property:CodeGenerationTypeScriptTestsWithDataVolumeOptions.name", "kind": "property", "name": "name", "declaration": "name?: string" }, { - "id": "property:WithDataVolumeOptions.isReadOnly", + "id": "property:CodeGenerationTypeScriptTestsWithDataVolumeOptions.isReadOnly", "kind": "property", "name": "isReadOnly", "declaration": "isReadOnly?: boolean" @@ -6259,21 +6259,21 @@ ] }, { - "id": "options:WithMergeLoggingOptions", + "id": "options:CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "kind": "options", - "name": "WithMergeLoggingOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingOptions", + "name": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithMergeLoggingOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "members": [ { - "id": "property:WithMergeLoggingOptions.enableConsole", + "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:WithMergeLoggingOptions.maxFiles", + "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6281,21 +6281,21 @@ ] }, { - "id": "options:WithMergeLoggingPathOptions", + "id": "options:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "kind": "options", - "name": "WithMergeLoggingPathOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingPathOptions", + "name": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithMergeLoggingPathOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "members": [ { - "id": "property:WithMergeLoggingPathOptions.enableConsole", + "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:WithMergeLoggingPathOptions.maxFiles", + "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6303,15 +6303,15 @@ ] }, { - "id": "options:WithOptionalCallbackOptions", + "id": "options:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "kind": "options", - "name": "WithOptionalCallbackOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalCallbackOptions", + "name": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithOptionalCallbackOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "members": [ { - "id": "property:WithOptionalCallbackOptions.callback", + "id": "property:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions.callback", "kind": "property", "name": "callback", "declaration": "callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E" @@ -6319,21 +6319,21 @@ ] }, { - "id": "options:WithOptionalStringOptions", + "id": "options:CodeGenerationTypeScriptTestsWithOptionalStringOptions", "kind": "options", - "name": "WithOptionalStringOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalStringOptions", + "name": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithOptionalStringOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions", "members": [ { - "id": "property:WithOptionalStringOptions.value", + "id": "property:CodeGenerationTypeScriptTestsWithOptionalStringOptions.value", "kind": "property", "name": "value", "declaration": "value?: string" }, { - "id": "property:WithOptionalStringOptions.enabled", + "id": "property:CodeGenerationTypeScriptTestsWithOptionalStringOptions.enabled", "kind": "property", "name": "enabled", "declaration": "enabled?: boolean" @@ -6341,15 +6341,15 @@ ] }, { - "id": "options:WithPersistenceOptions", + "id": "options:CodeGenerationTypeScriptTestsWithPersistenceOptions", "kind": "options", - "name": "WithPersistenceOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithPersistenceOptions", + "name": "CodeGenerationTypeScriptTestsWithPersistenceOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithPersistenceOptions", + "declaration": "export interface CodeGenerationTypeScriptTestsWithPersistenceOptions", "members": [ { - "id": "property:WithPersistenceOptions.mode", + "id": "property:CodeGenerationTypeScriptTestsWithPersistenceOptions.mode", "kind": "property", "name": "mode", "declaration": "mode?: TestPersistenceMode" @@ -6363,102 +6363,102 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResource {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResource {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResource {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResource {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResource {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResource {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Resource {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface Resource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface ResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString", @@ -6528,12 +6528,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext", @@ -6548,12 +6548,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", @@ -6568,62 +6568,62 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface AddTestChildDatabaseOptions {\n databaseName?: string;\n}" + "content": "export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions {\n databaseName?: string;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface AddTestRedisOptions {\n port?: number;\n}" + "content": "export interface CodeGenerationTypeScriptTestsAddTestRedisOptions {\n port?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsGetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface GetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithDataVolumeOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" + "content": "export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" + "content": "export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" + "content": "export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithPersistenceOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" + "content": "export interface CodeGenerationTypeScriptTestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" }, { "id": "Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle", diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts index dd69cd4d341..6bfef538a6d 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts @@ -1516,14 +1516,6 @@ export interface AddStepOptions { requiredBy?: string[]; } -export interface AddTestChildDatabaseOptions { - databaseName?: string; -} - -export interface AddTestRedisOptions { - port?: number; -} - export interface AppendFormattedOptions { /** The format to be applied to the value. e.g., "uri" */ format?: string; @@ -1545,6 +1537,50 @@ export interface BuildOptions { cancellationToken?: AbortSignal | CancellationToken; } +export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions { + databaseName?: string; +} + +export interface CodeGenerationTypeScriptTestsAddTestRedisOptions { + port?: number; +} + +export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; +} + +export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; +} + +export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { + name?: string; + isReadOnly?: boolean; +} + +export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions { + enableConsole?: boolean; + maxFiles?: number; +} + +export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions { + enableConsole?: boolean; + maxFiles?: number; +} + +export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions { + callback?: (arg: TestCallbackContext) => Promise; +} + +export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions { + value?: string; + enabled?: boolean; +} + +export interface CodeGenerationTypeScriptTestsWithPersistenceOptions { + mode?: TestPersistenceMode; +} + export interface CompleteStepMarkdownOptions { completionState?: string; cancellationToken?: AbortSignal | CancellationToken; @@ -1639,10 +1675,6 @@ export interface FromOptions { stageName?: string; } -export interface GetStatusAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; -} - export interface GetValueAsyncOptions { /** The cancellation token. */ cancellationToken?: AbortSignal | CancellationToken; @@ -1691,10 +1723,6 @@ export interface WaitForOptions { waitBehavior?: WaitBehavior; } -export interface WaitForReadyAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; -} - export interface WaitForResourceStateOptions { targetState?: string; } @@ -1722,11 +1750,6 @@ export interface WithContainerCertificatePathsOptions { defaultCertificateDirectoryPaths?: string[]; } -export interface WithDataVolumeOptions { - name?: string; - isReadOnly?: boolean; -} - export interface WithDescriptionOptions { /** A value indicating whether the description should be rendered as Markdown. `true` allows the description to contain Markdown elements such as links, text decoration and lists. */ enableMarkdown?: boolean; @@ -1863,33 +1886,10 @@ export interface WithMcpServerOptions { endpointName?: string; } -export interface WithMergeLoggingOptions { - enableConsole?: boolean; - maxFiles?: number; -} - -export interface WithMergeLoggingPathOptions { - enableConsole?: boolean; - maxFiles?: number; -} - -export interface WithOptionalCallbackOptions { - callback?: (arg: TestCallbackContext) => Promise; -} - -export interface WithOptionalStringOptions { - value?: string; - enabled?: boolean; -} - export interface WithOtlpExporterOptions { protocol?: OtlpProtocol; } -export interface WithPersistenceOptions { - mode?: TestPersistenceMode; -} - export interface WithPipelineStepFactoryOptions { /** Optional step names that this step depends on. */ dependsOn?: string[]; @@ -10946,7 +10946,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -11167,7 +11167,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addHealthCheck(name, check)), this._client); } - addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise { + addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.addTestRedis(name, options)), this._client); } @@ -14688,7 +14688,7 @@ export interface ContainerRegistryResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; /** Sets the created timestamp */ @@ -14701,7 +14701,7 @@ export interface ContainerRegistryResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; /** Configures with nested DTO */ @@ -14730,12 +14730,12 @@ export interface ContainerRegistryResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; /** Configures a route with middleware */ @@ -15005,7 +15005,7 @@ export interface ContainerRegistryResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -16508,7 +16508,7 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -16560,11 +16560,11 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -17335,7 +17335,7 @@ export interface ContainerResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -17350,7 +17350,7 @@ export interface ContainerResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -17381,12 +17381,12 @@ export interface ContainerResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -18144,7 +18144,7 @@ export interface ContainerResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -18159,7 +18159,7 @@ export interface ContainerResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -18190,12 +18190,12 @@ export interface ContainerResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -20543,7 +20543,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ContainerResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -20649,7 +20649,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise { const callback = options?.callback; return new ContainerResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -20877,7 +20877,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -20899,7 +20899,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -21318,7 +21318,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -21342,7 +21342,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -21398,11 +21398,11 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -21987,7 +21987,7 @@ export interface CSharpAppResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22002,7 +22002,7 @@ export interface CSharpAppResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22033,12 +22033,12 @@ export interface CSharpAppResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -22611,7 +22611,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22626,7 +22626,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22657,12 +22657,12 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -24569,7 +24569,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise { const value = options?.value; const enabled = options?.enabled; return new CSharpAppResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -24675,7 +24675,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise { const callback = options?.callback; return new CSharpAppResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -24903,7 +24903,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -24925,7 +24925,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -25276,7 +25276,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -25300,7 +25300,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -25356,11 +25356,11 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -25967,7 +25967,7 @@ export interface DotnetToolResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): DotnetToolResourcePromise; /** Configures environment with callback (test version) */ @@ -25982,7 +25982,7 @@ export interface DotnetToolResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): DotnetToolResourcePromise; /** Configures with nested DTO */ @@ -26013,12 +26013,12 @@ export interface DotnetToolResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; /** Configures a route with middleware */ @@ -26613,7 +26613,7 @@ export interface DotnetToolResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -29389,7 +29389,7 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -29445,11 +29445,11 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -30030,7 +30030,7 @@ export interface ExecutableResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExecutableResourcePromise; /** Configures environment with callback (test version) */ @@ -30045,7 +30045,7 @@ export interface ExecutableResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExecutableResourcePromise; /** Configures with nested DTO */ @@ -30076,12 +30076,12 @@ export interface ExecutableResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; /** Configures a route with middleware */ @@ -30643,7 +30643,7 @@ export interface ExecutableResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -33291,7 +33291,7 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -33347,11 +33347,11 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -33638,7 +33638,7 @@ export interface ExternalServiceResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExternalServiceResourcePromise; /** Sets the created timestamp */ @@ -33651,7 +33651,7 @@ export interface ExternalServiceResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; /** Configures with nested DTO */ @@ -33680,12 +33680,12 @@ export interface ExternalServiceResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; /** Configures a route with middleware */ @@ -33960,7 +33960,7 @@ export interface ExternalServiceResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -35491,7 +35491,7 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -35543,11 +35543,11 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -35843,7 +35843,7 @@ export interface ParameterResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -35856,7 +35856,7 @@ export interface ParameterResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -35885,12 +35885,12 @@ export interface ParameterResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -36173,7 +36173,7 @@ export interface ParameterResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -36186,7 +36186,7 @@ export interface ParameterResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -36215,12 +36215,12 @@ export interface ParameterResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -37182,7 +37182,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ParameterResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -37268,7 +37268,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise { const callback = options?.callback; return new ParameterResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -37481,7 +37481,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -37503,7 +37503,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -37706,7 +37706,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -37726,7 +37726,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -37778,11 +37778,11 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -38368,7 +38368,7 @@ export interface ProjectResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -38383,7 +38383,7 @@ export interface ProjectResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -38414,12 +38414,12 @@ export interface ProjectResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -38992,7 +38992,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -39007,7 +39007,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -39038,12 +39038,12 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -40951,7 +40951,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ProjectResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -41057,7 +41057,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise { const callback = options?.callback; return new ProjectResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -41285,7 +41285,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -41307,7 +41307,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -41658,7 +41658,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -41682,7 +41682,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -41738,11 +41738,11 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -42512,7 +42512,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -42527,7 +42527,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -42558,12 +42558,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -43321,7 +43321,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -46518,7 +46518,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -46574,11 +46574,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -47373,17 +47373,17 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -47404,7 +47404,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -47431,21 +47431,21 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: GetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -47458,12 +47458,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -48246,17 +48246,17 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -48277,7 +48277,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -48304,21 +48304,21 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: GetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -48331,12 +48331,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -50745,7 +50745,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -50765,7 +50765,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -50786,7 +50786,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -50925,7 +50925,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -51101,7 +51101,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: GetStatusAsyncOptions): Promise { + async getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51134,7 +51134,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51182,7 +51182,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -51264,7 +51264,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -51286,7 +51286,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -51717,15 +51717,15 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -51761,7 +51761,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -51809,7 +51809,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: GetStatusAsyncOptions): Promise { + getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -51817,7 +51817,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -51825,7 +51825,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -51845,11 +51845,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -52619,7 +52619,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -52634,7 +52634,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -52667,12 +52667,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -53430,7 +53430,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -53445,7 +53445,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -53478,12 +53478,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -55830,7 +55830,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -55936,7 +55936,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -56179,7 +56179,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -56201,7 +56201,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -56620,7 +56620,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -56644,7 +56644,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -56704,11 +56704,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -57310,7 +57310,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57323,7 +57323,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57352,12 +57352,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -57627,7 +57627,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57640,7 +57640,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57669,12 +57669,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -58595,7 +58595,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -58681,7 +58681,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -58894,7 +58894,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -58916,7 +58916,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -59111,7 +59111,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -59131,7 +59131,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -59183,11 +59183,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts index 81e32543081..0e65774a1fd 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts @@ -1,4 +1,4 @@ -export interface WithDataVolumeOptions { +export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } \ No newline at end of file From c7eacdaea5546a3d8654f852e7e4c6909f1d63b9 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 15:37:02 -0400 Subject: [PATCH 28/73] Pin export/generate naming agreement to the filtered context The determinism tests added with the owning-assembly naming change build projectors over raw hand-made contexts, but `sdk export` never hands the projector a raw scan: `FilterForApiExport` narrows it to the requested package first. That narrowing is the whole bug, so the property was proven about the projector rather than about the context the CLI produces. This goes through the filter and compares the export against the source the generator actually emits. Both packages are covered because only one of them fails under the old scheme, and it is not the obvious one: Event Hubs is scanned first and kept the unsuffixed base name in both views, so it agreed by luck. Comparing interface bodies rather than names is what makes the failure visible. Asserting only that the name appears in the generated source passes under the old scheme too, because the name did appear there -- it just belonged to the other package. Service Bus exported `RunAsEmulatorOptions` as `configureContainer?: boolean` while the SDK gave that same name to Event Hubs as `configureContainer?: string`, so a consumer concatenating the export got the wrong shape instead of a redeclaration error. Verified by reproducing the old naming locally: the Service Bus case fails with `Expected: "configureContainer?: boolean" / Actual: "configureContainer?: string"`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../AtsTypeScriptCodeGeneratorTests.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index ed079ef22eb..56855263aa5 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2598,6 +2598,56 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() Assert.Equal(CollisionPackageB, serviceBusDeclaration.OwningAssemblyName); } + /// + /// A per-package export names a colliding options interface the way full generation names it, + /// on the context the export path actually produces rather than on a raw scan. + /// + /// + /// The determinism test above compares projectors built directly over hand-made contexts, but + /// sdk export never hands the projector a raw scan: + /// narrows it to the requested package first. That difference is the whole bug — naming used to + /// be decided by collision detection over whatever the context happened to hold, so the narrowed + /// view and the full scan reached different answers for the same package. + /// + /// Both directions are checked because only one of them fails under the old scheme, and it is + /// not the obvious one. Event Hubs is scanned first, so it kept the unsuffixed base name in both + /// views and agreed by luck; Service Bus lost the draw during full generation and was suffixed + /// there while its own single-package export was not. Comparing interface bodies rather than + /// just names is what makes that failure visible: the old scheme had Service Bus export + /// RunAsEmulatorOptions as configureContainer?: boolean while the SDK gave that + /// same name to Event Hubs as configureContainer?: string, so a consumer concatenating + /// the export silently got the wrong shape rather than a redeclaration error. + /// + /// + [Theory] + [InlineData(CollisionPackageA, "AzureEventHubsRunAsEmulatorOptions")] + [InlineData(CollisionPackageB, "AzureServiceBusRunAsEmulatorOptions")] + public void ApiExportNamesACollidingOptionsInterfaceTheWayGenerationDoes(string packageName, string expectedInterfaceName) + { + var fullContext = CreateEmulatorCollisionContext(); + var exportContext = AtsContextFilter.FilterForApiExport(fullContext, [packageName]); + + var model = new TypeScriptApiProjector(exportContext).BuildApiModel( + new TypeScriptApiPackageIdentity(packageName, TestPackageVersion), + [packageName]); + + var exportedOptions = Assert.Single( + model.Modules.SelectMany(module => module.Items), + item => item.Kind == TypeScriptApiItemKind.Options); + + Assert.Equal(expectedInterfaceName, exportedOptions.Name); + Assert.Equal(packageName, exportedOptions.OwningAssemblyName); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(fullContext)["aspire.mts"]; + + var generatedInterfaces = ParsePublicInterfaceMembers(generatedSource); + Assert.Contains(exportedOptions.Name, generatedInterfaces.Keys); + Assert.Equal( + exportedOptions.Members.Select(member => member.Declaration).OrderBy(d => d, StringComparer.Ordinal), + generatedInterfaces[exportedOptions.Name].OrderBy(d => d, StringComparer.Ordinal)); + } + private const string CollisionPackageA = "Aspire.Hosting.Azure.EventHubs"; private const string CollisionPackageB = "Aspire.Hosting.Azure.ServiceBus"; From 60a57eaac3c51c5795db959da1f7597e1cbc1e91 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 15:41:04 -0400 Subject: [PATCH 29/73] Correct what the naming-agreement remark claims The remark described the intermediate version of the test rather than the committed one. It said only Service Bus fails under the old scheme and that Event Hubs "agreed by luck", which was true of the name-containment check I started with but not of the test as it stands: with the literal name assertions in place both rows fail, just at different assertions, Event Hubs on the name and Service Bus on the body. That mattered because a future reader reproducing the old-scheme experiment against the committed test would have seen Event Hubs fail and concluded the comment was wrong. The asymmetry is still the reason the body comparison exists, so the remark now explains it that way instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 93b90ae0-2187-486e-9bd2-a8ce41c09897 --- .../AtsTypeScriptCodeGeneratorTests.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 56855263aa5..01186823235 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2609,14 +2609,17 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() /// be decided by collision detection over whatever the context happened to hold, so the narrowed /// view and the full scan reached different answers for the same package. /// - /// Both directions are checked because only one of them fails under the old scheme, and it is - /// not the obvious one. Event Hubs is scanned first, so it kept the unsuffixed base name in both - /// views and agreed by luck; Service Bus lost the draw during full generation and was suffixed - /// there while its own single-package export was not. Comparing interface bodies rather than - /// just names is what makes that failure visible: the old scheme had Service Bus export - /// RunAsEmulatorOptions as configureContainer?: boolean while the SDK gave that - /// same name to Event Hubs as configureContainer?: string, so a consumer concatenating - /// the export silently got the wrong shape rather than a redeclaration error. + /// Both directions fail under the old scheme, but at different assertions, and that asymmetry + /// is why the body comparison is here. Event Hubs was scanned first and kept the unsuffixed + /// base name, so it fails only on the name: it produced RunAsEmulatorOptions rather than + /// AzureEventHubsRunAsEmulatorOptions. Service Bus lost that draw during full generation + /// and was suffixed there while its own single-package export was not, so it disagreed about + /// the interface itself. Checking only that the exported name appears among the generated names + /// would have missed it, because the name did appear -- it just belonged to Event Hubs. The old + /// scheme had Service Bus export RunAsEmulatorOptions as configureContainer?: boolean + /// while the SDK gave that same name to Event Hubs as configureContainer?: string, so a + /// consumer concatenating the export silently got the wrong callback type rather than a + /// redeclaration error. /// /// [Theory] From 2886db774c84cdfa044446180c2aa3eb2abfe413 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 16:50:00 -0400 Subject: [PATCH 30/73] Prune per-capability registries to the capabilities a scan keeps The capability ownership map, method registry, and property registry are all populated while assemblies are scanned, before FilterInvalidCapabilities and FilterMethodNameCollisions run. Those filters drop capabilities but cannot reach the registries, so an assembly whose every capability was filtered out stayed named by them. That is a silent failure rather than a leak. TryResolveCanonicalAssemblyName resolves a requested package against the assembly names these registries carry, so such a package resolved, filtered to nothing, and let `sdk export` publish an empty API document under a successful exit code. Pruning the ownership map alone is not sufficient: the method and property registries reach the same assembly through their declaring types, so canonicalization still succeeded. All three are pruned together. Removing the entries is safe because every consumer reaches them by the capability id of a capability it already holds. Both scan paths prune. Only the multi-assembly path -- the one `sdk export` uses -- can actually go stale today, since a capability id is `package/methodName` and two capabilities in one assembly cannot share a method name without sharing an id. The single-assembly path prunes for symmetry because it runs the same shared filters, and is covered by an invariant test rather than a reproduction. Also reverts the hand-edit to src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs. Files under */api/*.cs are generated and regenerated by the release process, not edited in individual PRs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../AtsCapabilityScanner.cs | 53 +++++++++++ .../api/Aspire.TypeSystem.cs | 18 ---- .../AtsCapabilityScannerTests.cs | 92 +++++++++++++++++++ .../AtsContextFilterTests.cs | 55 +++++++++++ 4 files changed, 200 insertions(+), 18 deletions(-) diff --git a/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs b/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs index c20302d6c47..f19649969e8 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs @@ -244,6 +244,8 @@ public static ScanResult ScanAssemblies( // Pass 5: Filter method name collisions (overloaded methods) after expansion FilterMethodNameCollisions(allCapabilities, allDiagnostics); + PruneRegistriesToSurvivingCapabilities(allCapabilities, allCapabilityExportingAssemblyNames, allMethods, allProperties); + return new ScanResult { Capabilities = allCapabilities, @@ -283,6 +285,8 @@ public static ScanResult ScanAssembly( // Filter method name collisions (overloaded methods) after expansion FilterMethodNameCollisions(result.Capabilities, result.Diagnostics); + PruneRegistriesToSurvivingCapabilities(result.Capabilities, result.CapabilityExportingAssemblyNames, result.Methods, result.Properties); + var exportedValues = DeduplicateExportedValues(result.ExportedValues, result.Diagnostics); return new ScanResult @@ -726,6 +730,55 @@ private static void ResolveTypeRef(AtsTypeRef? typeRef, HashSet validTyp } } + /// + /// Drops the per-capability registry entries for capabilities that scanning removed, so every + /// registry describes exactly the capabilities the scan kept. + /// + /// + /// + /// These registries are populated while assemblies are scanned, before + /// and run. + /// Those filters drop capabilities but cannot reach the registries, so an assembly whose every + /// capability was filtered out would still be named by them. + /// + /// + /// That is not cosmetic. AtsContextFilter.TryResolveCanonicalAssemblyName resolves a + /// requested package against the assembly names these registries carry, so such a package would + /// resolve, filter to nothing, and let sdk export publish an empty API document under a + /// successful exit code. Failing to resolve is what turns that into a reported error. The + /// ownership map alone is not enough: the method and property registries name the same assembly + /// through their declaring types. + /// + /// + /// Removing the entries is safe because every consumer reaches them by the capability id of a + /// capability it already holds, so an entry whose capability is gone is unreachable. + /// + /// + private static void PruneRegistriesToSurvivingCapabilities( + List capabilities, + Dictionary exportingAssemblyNames, + Dictionary methods, + Dictionary properties) + { + // Expansion mutates ExpandedTargetTypes in place and never rewrites CapabilityId, so the + // surviving ids are exactly the keys that should remain. + var survivingCapabilityIds = new HashSet( + capabilities.Select(capability => capability.CapabilityId), + StringComparer.Ordinal); + + RemoveStaleKeys(exportingAssemblyNames, survivingCapabilityIds); + RemoveStaleKeys(methods, survivingCapabilityIds); + RemoveStaleKeys(properties, survivingCapabilityIds); + + static void RemoveStaleKeys(Dictionary registry, HashSet survivingCapabilityIds) + { + foreach (var capabilityId in registry.Keys.Where(id => !survivingCapabilityIds.Contains(id)).ToList()) + { + registry.Remove(capabilityId); + } + } + } + /// /// Filters out capabilities that still have Unknown types after resolution. /// These are capabilities that use types not in the ATS universe. diff --git a/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs b/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs index 2c8b3be551d..83f42638aab 100644 --- a/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs +++ b/src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs @@ -8,17 +8,6 @@ //------------------------------------------------------------------------------ namespace Aspire.TypeSystem { - public sealed partial class ApiReferenceExportOptions - { - public ApiReferenceExportOptions(string packageName, string packageVersion, System.Collections.Generic.IReadOnlyCollection exportingAssemblyNames) { } - - public System.Collections.Generic.IReadOnlyCollection ExportingAssemblyNames { get { throw null; } } - - public string PackageName { get { throw null; } } - - public string PackageVersion { get { throw null; } } - } - public sealed partial class AspireExportData { public string? Description { get { throw null; } init { } } @@ -470,13 +459,6 @@ public static partial class HostingTypeNames public const string ValueProviderInterface = "Aspire.Hosting.ApplicationModel.IValueProvider"; } - public partial interface IApiReferenceExporter - { - string Language { get; } - - System.Text.Json.JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options); - } - public partial interface ICodeGenerator { string Language { get; } diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs index 573dd4cb2f5..01daf06b789 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs @@ -563,6 +563,68 @@ public void ScanAssemblies_AssemblyLevelExportedTypes_AreResolvedAcrossScanOrder AtsCapabilityScanner.MapToAtsTypeId(typeof(AssemblyLevelExportedTestType))); } + /// + /// The ownership map is merged while assemblies are scanned, before the capability filters run. + /// An assembly whose every capability is filtered out must not stay in it: the map's values are + /// what AtsContextFilter.TryResolveCanonicalAssemblyName resolves a requested package + /// against, so a stale entry lets sdk export resolve the package, filter to nothing, and + /// report success while publishing an empty API document. + /// + /// + /// A method name collision is the reachable way to lose a capability after the map is built. + /// A capability whose parameter types do not map is skipped during discovery, so it never enters + /// the map in the first place; collisions are only detected once every assembly has been scanned. + /// Ordinal capability id order decides the loser, so the two assembly names are chosen to sort. + /// + [Fact] + public void ScanAssemblies_CapabilityLostToACollision_DropsItsAssemblyFromExportingAssemblyNames() + { + var hostingAssembly = typeof(IDistributedApplicationBuilder).Assembly; + var winningAssembly = CreateCollidingCapabilityAssembly("AaaCollisionWinner", "collidingExport"); + var losingAssembly = CreateCollidingCapabilityAssembly("ZzzCollisionLoser", "collidingExport"); + + var result = AtsCapabilityScanner.ScanAssemblies([hostingAssembly, winningAssembly, losingAssembly]); + + var losingAssemblyName = losingAssembly.GetName().Name!; + var winningAssemblyName = winningAssembly.GetName().Name!; + + Assert.Equal( + [winningAssemblyName], + result.Capabilities + .Where(c => c.CapabilityId.EndsWith("/collidingExport", StringComparison.Ordinal)) + .Select(c => c.CapabilityId.Split('/')[0]) + .Order(StringComparer.Ordinal)); + Assert.Equal( + new[] { hostingAssembly.GetName().Name!, winningAssemblyName }.Order(StringComparer.Ordinal), + result.CapabilityExportingAssemblyNames.Values.Distinct(StringComparer.Ordinal).Order(StringComparer.Ordinal)); + Assert.Equal( + result.Capabilities.Select(c => c.CapabilityId).Order(StringComparer.Ordinal), + result.CapabilityExportingAssemblyNames.Keys.Order(StringComparer.Ordinal)); + } + + /// + /// The single-assembly scan path builds the same registries ahead of the same filters and prunes + /// them for the same reason, so every registry must describe exactly the capabilities it kept. + /// + /// + /// This is an invariant guard rather than a reproduction. A capability id is + /// package/methodName, so two capabilities in one assembly cannot share a method name + /// without sharing an id, which makes an intra-assembly collision unremovable. The pruning this + /// asserts is reachable through FilterInvalidCapabilities, which both scan paths share. + /// + [Fact] + public void ScanAssembly_PerCapabilityRegistriesDescribeExactlyTheSurvivingCapabilities() + { + var result = AtsCapabilityScanner.ScanAssembly(typeof(IDistributedApplicationBuilder).Assembly); + + var survivingCapabilityIds = result.Capabilities.Select(c => c.CapabilityId).Distinct(StringComparer.Ordinal).Order(StringComparer.Ordinal).ToList(); + + Assert.NotEmpty(survivingCapabilityIds); + Assert.Equal(survivingCapabilityIds, result.CapabilityExportingAssemblyNames.Keys.Order(StringComparer.Ordinal)); + Assert.Empty(result.Methods.Keys.Except(survivingCapabilityIds, StringComparer.Ordinal)); + Assert.Empty(result.Properties.Keys.Except(survivingCapabilityIds, StringComparer.Ordinal)); + } + [Fact] public void ScanAssembly_YarpWithConfiguration_UsesBackgroundThreadOptIn() { @@ -928,6 +990,36 @@ public static class Node } } + /// + /// Builds a dynamic assembly exporting a single capability under a caller-chosen method name, so + /// two of them can be made to collide on the same target. + /// + private static Assembly CreateCollidingCapabilityAssembly(string assemblyNamePrefix, string methodName) + { + var assemblyName = new AssemblyName($"{assemblyNamePrefix}_{Guid.NewGuid():N}"); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name!); + var exportsTypeBuilder = moduleBuilder.DefineType( + "Generated.CollidingExports", + TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed); + var methodBuilder = exportsTypeBuilder.DefineMethod( + "Collides", + MethodAttributes.Public | MethodAttributes.Static, + typeof(void), + [typeof(IDistributedApplicationBuilder), typeof(string)]); + methodBuilder.DefineParameter(1, ParameterAttributes.None, "builder"); + methodBuilder.DefineParameter(2, ParameterAttributes.None, "value"); + methodBuilder.SetCustomAttribute( + new CustomAttributeBuilder( + typeof(AspireExportAttribute).GetConstructor([typeof(string)])!, + [methodName])); + methodBuilder.GetILGenerator().Emit(OpCodes.Ret); + + _ = exportsTypeBuilder.CreateType(); + + return assemblyBuilder; + } + private static Assembly CreateAssemblyLevelExportCapabilityAssembly(Type parameterType) { var assemblyName = new AssemblyName($"AssemblyLevelExportCapability_{Guid.NewGuid():N}"); diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index 17502dbb402..527ae9eca58 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Reflection; +using System.Reflection.Emit; using System.Text.Json.Nodes; using Aspire.Hosting.ApplicationModel; using Aspire.TypeSystem; @@ -79,6 +80,60 @@ public enum NameCasing AsDeclared } + /// + /// An assembly whose capabilities were all removed by scan-time filtering exports nothing, so + /// canonicalization has to reject it. Resolving it instead is the silent failure: the export + /// filters to nothing and sdk export publishes an empty document under a successful exit + /// code rather than telling the caller the package contributed no API. + /// + [Fact] + public void TryResolveCanonicalAssemblyName_RejectsAnAssemblyWhoseCapabilitiesWereAllFiltered() + { + var losingAssembly = CreateCollidingCapabilityAssembly("ZzzFilterCollisionLoser"); + var context = AtsCapabilityScanner.ScanAssemblies( + [ + typeof(IDistributedApplicationBuilder).Assembly, + CreateCollidingCapabilityAssembly("AaaFilterCollisionWinner"), + losingAssembly + ]).ToAtsContext(); + var losingAssemblyName = losingAssembly.GetName().Name!; + + Assert.False(AtsContextFilter.TryResolveCanonicalAssemblyName(context, losingAssemblyName, out var resolvedName)); + Assert.Null(resolvedName); + Assert.Empty(AtsContextFilter.FilterByExportingAssemblies(context, [losingAssemblyName]).Capabilities); + } + + /// + /// A dynamic assembly whose single capability collides with an identically named export on the + /// same target, so the scan keeps only the ordinally first one and the other assembly is left + /// contributing nothing. + /// + private static Assembly CreateCollidingCapabilityAssembly(string assemblyNamePrefix) + { + var assemblyName = new AssemblyName($"{assemblyNamePrefix}_{Guid.NewGuid():N}"); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name!); + var exportsTypeBuilder = moduleBuilder.DefineType( + "Generated.CollidingExports", + TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed); + var methodBuilder = exportsTypeBuilder.DefineMethod( + "Collides", + MethodAttributes.Public | MethodAttributes.Static, + typeof(void), + [typeof(IDistributedApplicationBuilder), typeof(string)]); + methodBuilder.DefineParameter(1, ParameterAttributes.None, "builder"); + methodBuilder.DefineParameter(2, ParameterAttributes.None, "value"); + methodBuilder.SetCustomAttribute( + new CustomAttributeBuilder( + typeof(AspireExportAttribute).GetConstructor([typeof(string)])!, + ["collidingExport"])); + methodBuilder.GetILGenerator().Emit(OpCodes.Ret); + + _ = exportsTypeBuilder.CreateType(); + + return assemblyBuilder; + } + [Fact] public void FilterByExportingAssemblies_StrictFilterKeepsOnlySelectedAssemblyExports() { From e30db3cd355b2f2cedb4fae87db4061476f9b1b6 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 7 Aug 2026 18:11:46 -0400 Subject: [PATCH 31/73] Fix three identity bugs in TypeScript export naming and gating Options interface qualifiers were not injective. The qualifier kept only letters and digits, so Contoso.Foo.Bar and Contoso.FooBar both produced ContosoFooBar. A per-package export cannot see that another package lands on the same qualifier, so it has no chance to disambiguate the way full generation would; both packages emit a ContosoFooBarRunAsEmulatorOptions with different members and concatenating their fragments fails to compile. The separator is now encoded rather than dropped, which is reversible and therefore injective. An assembly name beginning with a digit also produced an unparseable TypeScript identifier, so that case is escaped. Entry points were exported with the wrong signature. ProjectEntryPoint routed through the member signature resolver, which drops the client parameter and folds optionals into an options bag, while GenerateEntryPointFunction emits a free function taking the client first and keeping optionals positional. Consumers type-check against the exported declarations, so the two disagreeing published declarations that describe no callable function. Both paths now resolve through ResolveEntryPointSignature. The core export was gated on IdentityOverridden, an aggregate that is true whenever any identity field came from an environment variable or the install sidecar. Every install route writes a sidecar carrying channel and version, so the aggregate is set on ordinary installs and the guard rejected exactly the CLIs its own error message told callers to use. Only a version supplied by ASPIRE_CLI_VERSION makes the label unverifiable, so IdentityVersionForged tracks that specifically. Each fix has a test that fails without it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Aspire.Cli/CliExecutionContext.cs | 17 +- .../Commands/Sdk/SdkExportCommand.cs | 28 +- src/Aspire.Cli/Program.cs | 7 + .../AtsTypeScriptCodeGenerator.cs | 18 +- .../TypeScriptApiProjector.cs | 149 +++++- .../Commands/Sdk/SdkExportCommandTests.cs | 49 +- .../Utils/TestExecutionContextHelper.cs | 10 +- .../AtsTypeScriptCodeGeneratorTests.cs | 146 +++++- .../Snapshots/AtsGeneratedAspire.verified.ts | 204 ++++---- ...eneratorTests.ApiDeclarations.verified.txt | 256 +++++----- ...CodeGeneratorTests.ApiExport.verified.json | 416 ++++++++-------- ...TwoPassScanningGeneratedAspire.verified.ts | 452 +++++++++--------- .../WithDataVolumeOptionsMerged.verified.ts | 2 +- 13 files changed, 1031 insertions(+), 723 deletions(-) diff --git a/src/Aspire.Cli/CliExecutionContext.cs b/src/Aspire.Cli/CliExecutionContext.cs index 79c6eee64b8..0837414b917 100644 --- a/src/Aspire.Cli/CliExecutionContext.cs +++ b/src/Aspire.Cli/CliExecutionContext.cs @@ -7,7 +7,7 @@ namespace Aspire.Cli; -internal sealed class CliExecutionContext(DirectoryInfo workingDirectory, DirectoryInfo hivesDirectory, DirectoryInfo cacheDirectory, DirectoryInfo sdksDirectory, DirectoryInfo logsDirectory, string logFilePath, string identityChannel, bool debugMode = false, DirectoryInfo? homeDirectory = null, DirectoryInfo? packagesDirectory = null, DirectoryInfo? aspireHomeDirectory = null, string? identityVersion = null, string? identityCommit = null, string? nugetServiceIndexOverride = null, bool identityOverridden = false, DirectoryInfo? identityPackagesDirectory = null) +internal sealed class CliExecutionContext(DirectoryInfo workingDirectory, DirectoryInfo hivesDirectory, DirectoryInfo cacheDirectory, DirectoryInfo sdksDirectory, DirectoryInfo logsDirectory, string logFilePath, string identityChannel, bool debugMode = false, DirectoryInfo? homeDirectory = null, DirectoryInfo? packagesDirectory = null, DirectoryInfo? aspireHomeDirectory = null, string? identityVersion = null, string? identityCommit = null, string? nugetServiceIndexOverride = null, bool identityOverridden = false, DirectoryInfo? identityPackagesDirectory = null, bool identityVersionForged = false) { public DirectoryInfo WorkingDirectory { get; } = workingDirectory; public DirectoryInfo HivesDirectory { get; } = hivesDirectory; @@ -103,6 +103,21 @@ internal sealed class CliExecutionContext(DirectoryInfo workingDirectory, Direct /// public bool IdentityOverridden { get; } = identityOverridden; + /// + /// Gets a value indicating whether specifically was supplied by an + /// ASPIRE_CLI_VERSION environment variable. + /// + /// + /// This is deliberately narrower than , which is an aggregate + /// over every identity field and counts the install sidecar as an override. Every install route + /// writes a sidecar carrying channel and version (see + /// docs/specs/cli-identity-sidecar.md), so is + /// for a perfectly ordinary installed CLI and cannot be used to decide + /// whether a version label is trustworthy. The sidecar records what was actually installed; only + /// an environment variable makes the version a per-run claim the CLI cannot stand behind. + /// + public bool IdentityVersionForged { get; } = identityVersionForged; + /// /// Optional replacement for the canonical /// https://api.nuget.org/v3/index.json URL when the CLI emits diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index ac5d869964a..d6d70617885 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -244,8 +244,10 @@ private static string StripBuildMetadata(string version) /// version. The comparison that enforces that runs before any project is created, but it /// compares the request against the identity while the default request is the identity, /// so on its own it only catches an explicitly wrong --package. Two cases get past it. - /// An identity override makes the identity itself caller-controlled, and the prebuilt scanner - /// has no second signal to check it against, so an override is refused outright. Repository mode + /// An ASPIRE_CLI_VERSION override makes the identity itself caller-controlled, and the + /// prebuilt scanner has no second signal to check it against, so that override is refused + /// outright. It has to be that specific signal rather than the IdentityOverridden + /// aggregate, which every installed CLI trips through its install sidecar. Repository mode /// is entered through ASPIRE_REPO_ROOT, which is not an identity field at all, so an /// installed CLI can be pointed at a checkout on a different version line with no override in /// effect; the core package therefore falls through to the same checkout comparison every other @@ -261,13 +263,18 @@ private static string StripBuildMetadata(string version) { var isCorePackage = string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase); - if (isCorePackage && ExecutionContext.IdentityOverridden) + if (isCorePackage && ExecutionContext.IdentityVersionForged) { // The prebuilt scanner has no second signal: the core assemblies come from the bundle - // this CLI shipped with, so an override leaves nothing to check the label against. + // this CLI shipped with, so a forged version leaves nothing to check the label against. // Repository mode does have one, and falls through to it below. + // + // This tests IdentityVersionForged rather than the IdentityOverridden aggregate on + // purpose. Every install route writes a sidecar carrying channel and version, so the + // aggregate is true for an ordinary installed CLI and gating on it rejected the + // advertised default export on exactly the installs the error told callers to use. return $"The scanner loads the {CorePackageName} assemblies this CLI ships with, so an export of it describes this CLI. " + - $"This run emulates a different build through an ASPIRE_CLI_* override, so the export cannot be attributed to a real build of {packageVersion}. " + + $"This run claims a different version through ASPIRE_CLI_VERSION, so the export cannot be attributed to a real build of {packageVersion}. " + $"Re-run without the override, or export {CorePackageName} from an installed CLI."; } @@ -283,12 +290,13 @@ private static string StripBuildMetadata(string version) var preamble = $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {substitution.ProjectPath} " + $"instead of being restored from a package feed."; - if (ExecutionContext.IdentityOverridden) + if (ExecutionContext.IdentityVersionForged) { - // An ASPIRE_CLI_* override makes this run an emulation of a build the checkout is not, - // which is exactly the combination that cannot be checked: both the source and the label - // are caller-controlled. The overrides stay available for every non-substituted path. - return $"{preamble} This run also has an ASPIRE_CLI_* identity override in effect, so nothing can confirm the " + + // A forged version makes this run an emulation of a build the checkout is not, which is + // exactly the combination that cannot be checked: both the source and the label are + // caller-controlled. Every other ASPIRE_CLI_* override stays available here, and a + // sidecar version does not qualify because the installer wrote it. + return $"{preamble} This run also claims a version through ASPIRE_CLI_VERSION, so nothing can confirm the " + $"checkout really is {packageVersion}. Re-run without the override, or export {packageName} from an installed CLI."; } diff --git a/src/Aspire.Cli/Program.cs b/src/Aspire.Cli/Program.cs index 0e53283941b..f80776e33cc 100644 --- a/src/Aspire.Cli/Program.cs +++ b/src/Aspire.Cli/Program.cs @@ -719,6 +719,12 @@ internal static CliExecutionContext BuildCliExecutionContext(bool debugMode, str static bool IsOverride(IdentitySource source) => source is IdentitySource.Environment or IdentitySource.Sidecar; var identityOverridden = IsOverride(channel.Source) || IsOverride(version.Source) || IsOverride(commit.Source) || IsOverride(nugetServiceIndexOverride.Source) || IsOverride(packagesOverride.Source); + // Tracked separately from the aggregate above because callers that need to trust the version + // label cannot use the aggregate: the sidecar is written by every install route, so the + // aggregate is true for an ordinary installed CLI. Only the environment variable makes the + // version a claim this run invented. + var identityVersionForged = version.Source is IdentitySource.Environment; + // A null/whitespace value means "no override"; only materialize a DirectoryInfo when a real // path was supplied. PackagingService validates existence + uniqueness when it consumes this. var identityPackagesDirectory = string.IsNullOrWhiteSpace(packagesOverride.Value) @@ -738,6 +744,7 @@ internal static CliExecutionContext BuildCliExecutionContext(bool debugMode, str nugetServiceIndexOverride: nugetServiceIndexOverride.Value, identityOverridden: identityOverridden, identityPackagesDirectory: identityPackagesDirectory, + identityVersionForged: identityVersionForged, debugMode: debugMode, packagesDirectory: packagesDirectory, aspireHomeDirectory: aspireHomeDirectory); diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index 7dac5819ffa..8e04c4f871e 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -1864,16 +1864,10 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) { var methodName = capability.MethodName; - // Build parameter list - var paramDefs = new List { "client: AspireClientRpc" }; - foreach (var param in capability.Parameters) - { - var tsType = _projector.MapParameterToTypeScript(param); - var optional = param.IsOptional || param.IsNullable ? "?" : ""; - paramDefs.Add($"{param.Name}{optional}: {tsType}"); - } - - var paramsString = string.Join(", ", paramDefs); + // Resolved once and shared with the canonical exporter so the emitted function and the + // declaration that documents it cannot describe different parameter lists. + var signature = _projector.ResolveEntryPointSignature(capability); + var paramsString = signature.ParameterList; var (requiredParams, optionalParams) = TypeScriptApiProjector.SeparateParameters(capability.Parameters); // Determine return type - check if return type has a Promise wrapper @@ -1895,7 +1889,7 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) Write($"export function {methodName}("); Write(paramsString); - WriteLine($"): {returnPromiseWrapper} {{"); + WriteLine($"): {signature.ReturnType} {{"); // Use async IIFE to resolve promise-like handle params before RPC WriteLine($" const promise = (async () => {{"); // Resolve promise-like handle params @@ -1933,7 +1927,7 @@ private void GenerateEntryPointFunction(AtsCapabilityInfo capability) Write($"export async function {methodName}("); Write(paramsString); - WriteLine($"): Promise<{returnType}> {{"); + WriteLine($"): {signature.ReturnType} {{"); // Resolve promise-like handle params foreach (var param in capability.Parameters) { diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 3aa2afed778..bd6e364bc4b 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Globalization; using System.Text; using System.Text.RegularExpressions; using Aspire.Shared.CodeGeneration; @@ -69,6 +70,12 @@ export interface InteractionInputCollectionPromise extends PromiseLikeThe client parameter every entry-point function takes first. + private const string EntryPointClientParameterName = "client"; + + /// The declared type of . + private const string EntryPointClientParameterType = "AspireClientRpc"; + private static readonly string[] s_optionsInterfaceQualifierPrefixes = [ $"{AtsConstants.AspireHostingAssembly}.", @@ -852,7 +859,8 @@ private TypeScriptApiMember ProjectProperty( private TypeScriptApiItem ProjectEntryPoint(TypeScriptApiPackageIdentity package, AtsCapabilityInfo capability) { - var member = ProjectMethod(package.Name, builderModel: null, capability); + _ = package; + var signature = ResolveEntryPointSignature(capability); return new TypeScriptApiItem { @@ -860,14 +868,78 @@ private TypeScriptApiItem ProjectEntryPoint(TypeScriptApiPackageIdentity package TypeId = capability.CapabilityId, Kind = TypeScriptApiItemKind.Method, Name = capability.MethodName, - Declaration = member.Declaration, + Declaration = $"function {signature.Declaration}", OwningAssemblyName = GetCapabilityOwningAssemblyName(capability), - Summary = member.Summary, - Remarks = member.Remarks, + Summary = capability.Documentation?.Summary, + Remarks = capability.Documentation?.Remarks, Members = [] }; } + /// + /// Resolves the signature of an entry-point capability -- one that hangs off the client rather + /// than a builder type -- for both the emitted function and the exported declaration. + /// + /// + /// + /// Entry points are shaped unlike every other capability, which is why they cannot share + /// . They are free functions rather than members, so the + /// client has to be passed explicitly as the first parameter, and their optional arguments stay + /// positional instead of collapsing into an options bag. + /// + /// + /// Routing through gave the + /// export the member shape -- no client, optionals folded into an options interface -- + /// while GenerateEntryPointFunction emitted the free-function shape. Consumers type-check + /// the exported declarations against the generated SDK, so the two disagreeing produced + /// declarations that did not describe any callable function. + /// + /// + internal TypeScriptApiMethodSignature ResolveEntryPointSignature(AtsCapabilityInfo capability) + { + ArgumentNullException.ThrowIfNull(capability); + + var (requiredParameters, _) = SeparateParameters(capability.Parameters); + + var parameters = new List + { + new() { Name = EntryPointClientParameterName, DeclaredType = EntryPointClientParameterType, IsOptional = false } + }; + + foreach (var parameter in capability.Parameters) + { + parameters.Add(new TypeScriptApiParameter + { + Name = parameter.Name, + DeclaredType = MapParameterToTypeScript(parameter), + IsOptional = parameter.IsOptional || parameter.IsNullable, + Summary = parameter.Documentation?.Summary + }); + } + + return new TypeScriptApiMethodSignature + { + MethodName = capability.MethodName, + ReturnType = ResolveEntryPointReturnType(capability), + Parameters = parameters, + RequiredParameters = requiredParameters + }; + } + + private string ResolveEntryPointReturnType(AtsCapabilityInfo capability) + { + var returnTypeId = capability.ReturnType?.TypeId; + + // A capability that returns a wrapped handle is emitted as a fluent function returning the + // promise wrapper directly, so it is already thenable and is not wrapped again. + if (GetPromiseWrapperForReturnType(capability.ReturnType) is { } promiseWrapper && !string.IsNullOrEmpty(returnTypeId)) + { + return promiseWrapper; + } + + return $"Promise<{(string.IsNullOrEmpty(returnTypeId) ? "void" : MapTypeRefToTypeScript(capability.ReturnType))}>"; + } + private static (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) ProjectEnum(AtsEnumTypeInfo enumType) { var owningAssemblyName = GetOwningAssemblyName(enumType.TypeId, enumType.ClrType?.Assembly.GetName().Name); @@ -1608,15 +1680,10 @@ internal static string ToPascalCase(string name) /// The core hosting package keeps unqualified names. It is present in every scan, so its names /// were never the ones at risk, and leaving them alone confines the rename to the packages that /// actually needed it. The qualifier drops a leading Aspire.Hosting. (or Aspire.) - /// and the dots, so Aspire.Hosting.Azure.EventHubs yields - /// AzureEventHubsRunAsEmulatorOptions and Aspire.Hosting.Redis yields - /// RedisWithDataVolumeOptions. - /// - /// - /// Two assemblies whose names differ only by where the dots fall (Aspire.Hosting.Foo.Bar - /// and Aspire.Hosting.FooBar) would collapse to one qualifier. That pair does not exist, - /// and the suffix loop in still keeps the output - /// well-formed if it ever does, so it is not worth a longer name for every package to prevent. + /// and encodes the remaining separators, so Aspire.Hosting.Azure.EventHubs yields + /// Azure_EventHubsRunAsEmulatorOptions and Aspire.Hosting.Redis yields + /// RedisWithDataVolumeOptions. See for why the + /// encoding has to be reversible rather than simply stripping the punctuation. /// /// internal static string GetOptionsInterfaceName(string methodName, string owningAssemblyName) @@ -1633,6 +1700,23 @@ internal static string GetOptionsInterfaceName(string methodName, string owningA /// Derives the name-space prefix an assembly's options interfaces carry, or an empty string for /// the core hosting package and for symbols whose owner could not be resolved. /// + /// + /// + /// The encoding has to be injective. A per-package export sees only its own assemblies, so it + /// cannot detect that some other package would produce the same qualifier and disambiguate the + /// way full generation could. Two assemblies that collide here would emit conflicting options + /// interfaces that fail to compile once both package exports are concatenated, which is the + /// failure this qualifier exists to prevent. Simply dropping separators is not injective: + /// Contoso.Foo.Bar and Contoso.FooBar would both yield ContosoFooBar. + /// + /// + /// So separators are encoded rather than removed. '.' becomes '_', a literal + /// '_' is doubled, and any other character becomes _x followed by its hex code + /// point. Every rule is reversible, so distinct assembly names cannot share a qualifier. + /// Assembly and package identity is case-insensitive, so casing alone never distinguishes two + /// assemblies and normalizing the first character is safe. + /// + /// private static string GetOptionsInterfaceQualifier(string owningAssemblyName) { if (string.IsNullOrEmpty(owningAssemblyName) || @@ -1651,18 +1735,47 @@ private static string GetOptionsInterfaceQualifier(string owningAssemblyName) } } - // Assembly names are dotted identifiers, so dropping the separators is enough to reach a - // legal TypeScript identifier; anything else is defensive against a name that is not. var qualifier = new StringBuilder(remainder.Length); foreach (var character in remainder) { - if (char.IsLetterOrDigit(character)) + switch (character) { - qualifier.Append(character); + case '.': + qualifier.Append('_'); + break; + case '_': + qualifier.Append("__"); + break; + default: + if (char.IsAsciiLetterOrDigit(character)) + { + qualifier.Append(character); + } + else + { + qualifier.Append("_x").Append(((int)character).ToString("X2", CultureInfo.InvariantCulture)); + } + + break; } } - return qualifier.Length == 0 ? string.Empty : ToPascalCase(qualifier.ToString()); + if (qualifier.Length == 0) + { + return string.Empty; + } + + // A TypeScript identifier cannot start with a digit, and an assembly name legitimately can + // (for example "3rdParty.Aspire"). Prefixing keeps the result parseable, and cannot alias a + // name that already begins with '_' because that character encodes to a doubled '_'. + if (char.IsAsciiDigit(qualifier[0])) + { + qualifier.Insert(0, '_'); + + return qualifier.ToString(); + } + + return ToPascalCase(qualifier.ToString()); } /// diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 611b9f7137c..0af9cc03bfc 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -293,7 +293,8 @@ public async Task SdkExportRejectsASubstitutedPackageWhenTheCliIdentityIsOverrid rpcClient, appHostServerProject, identityVersion: "13.5.0", - identityOverridden: true); + identityOverridden: true, + identityVersionForged: true); appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", "13.5.0"); var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); @@ -303,6 +304,41 @@ public async Task SdkExportRejectsASubstitutedPackageWhenTheCliIdentityIsOverrid Assert.Empty(interactionService.DisplayedRawText); } + /// + /// A normally installed CLI can export the core package, which is the command's advertised + /// default invocation. + /// + /// + /// The guard used to test IdentityOverridden, an aggregate that is + /// whenever any identity field came from an environment variable + /// or the install sidecar. Every install route writes a sidecar carrying channel and + /// version, so the aggregate is set on ordinary installs and the guard rejected precisely the + /// CLIs its own error message told callers to use. Only a version this run invented can make + /// the label unverifiable, so that is what the guard tests. + /// + [Fact] + public async Task SdkExportOfTheCorePackageAcceptsASidecarSuppliedIdentity() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.5.0", + identityOverridden: true, + identityVersionForged: false); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); + + Assert.Equal(0, exitCode); + var request = Assert.NotNull(rpcClient.LastExportRequest); + Assert.Equal("Aspire.Hosting", request.PackageName); + } + /// /// When the checkout cannot say what it builds there is nothing left to check the label against, /// and an unverifiable label is the failure mode this command exists to prevent. @@ -346,7 +382,8 @@ public async Task SdkExportOfTheCorePackageRejectsAnOverriddenCliIdentity() rpcClient, appHostServerProject, identityVersion: "99.0.0", - identityOverridden: true); + identityOverridden: true, + identityVersionForged: true); // No --package at all, so this is the default invocation: Aspire.Hosting at the identity // version. Without the guard this publishes the current core surface as 99.0.0. @@ -605,17 +642,19 @@ private ServiceProvider CreateProvider( IAppHostRpcClient rpcClient, IAppHostServerProject appHostServerProject, string? identityVersion = null, - bool identityOverridden = false) + bool identityOverridden = false, + bool identityVersionForged = false) { var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper, options => { options.InteractionServiceFactory = _ => interactionService; - if (identityVersion is not null || identityOverridden) + if (identityVersion is not null || identityOverridden || identityVersionForged) { options.CliExecutionContextFactory = _ => TestExecutionContextHelper.CreateExecutionContext( workspace.WorkspaceRoot, identityVersion: identityVersion, - identityOverridden: identityOverridden); + identityOverridden: identityOverridden, + identityVersionForged: identityVersionForged); } }); diff --git a/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs b/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs index 422f49f670a..53d7fe03307 100644 --- a/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs +++ b/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs @@ -22,7 +22,8 @@ public static CliExecutionContext CreateExecutionContext( string? logFilePath = null, string? identityVersion = null, string? identityCommit = null, - bool identityOverridden = false) + bool identityOverridden = false, + bool identityVersionForged = false) { return CreateExecutionContext( workspace.WorkspaceRoot, @@ -30,7 +31,8 @@ public static CliExecutionContext CreateExecutionContext( logFilePath: logFilePath, identityVersion: identityVersion, identityCommit: identityCommit, - identityOverridden: identityOverridden); + identityOverridden: identityOverridden, + identityVersionForged: identityVersionForged); } /// @@ -49,7 +51,8 @@ public static CliExecutionContext CreateExecutionContext( string? identityVersion = null, string? identityCommit = null, bool identityOverridden = false, - DirectoryInfo? identityPackagesDirectory = null) + DirectoryInfo? identityPackagesDirectory = null, + bool identityVersionForged = false) { var root = rootDirectory.FullName; hivesDirectory ??= new DirectoryInfo(Path.Combine(root, ".aspire", "hives")); @@ -72,6 +75,7 @@ public static CliExecutionContext CreateExecutionContext( nugetServiceIndexOverride: null, identityOverridden: identityOverridden, identityPackagesDirectory: identityPackagesDirectory, + identityVersionForged: identityVersionForged, debugMode: debugMode, homeDirectory: homeDirectory, packagesDirectory: packagesDirectory); diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 01186823235..c323d6b940f 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1925,7 +1925,7 @@ public void Scanner_PackageManagerMethods_ExpandToAllJavaScriptResourceTypes(str /// alongside every other package. Only Aspire.Hosting keeps unqualified names, so the /// fixture's own interfaces carry this prefix. /// - private const string TestOptionsPrefix = "CodeGenerationTypeScriptTests"; + private const string TestOptionsPrefix = "CodeGeneration_TypeScript_Tests"; [Fact] public async Task ApiExportUsesTheSameResolvedSignaturesAsGeneratedSource() @@ -2547,8 +2547,8 @@ static string EmulatorInterfaceName(TypeScriptApiProjector projector, string pac => projector.ResolveOptionsInterfaceName( projector.Resolved.Context.Capabilities.Single(c => c.CapabilityId == $"{packageName}/runAsEmulator")); - Assert.Equal("AzureEventHubsRunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); - Assert.Equal("AzureServiceBusRunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); + Assert.Equal("Azure_EventHubsRunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); + Assert.Equal("Azure_ServiceBusRunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); Assert.Equal( EmulatorInterfaceName(hubsAlone, CollisionPackageA), @@ -2558,6 +2558,88 @@ static string EmulatorInterfaceName(TypeScriptApiProjector projector, string pac EmulatorInterfaceName(scannedTogether, CollisionPackageB)); } + /// + /// An entry point's exported declaration describes the function the generator actually emits. + /// + /// + /// Entry points are free functions, so the generator emits them taking the client explicitly and + /// keeping optional arguments positional. The exporter used to route them through the member + /// signature resolver instead, which dropped client and folded the optionals into an + /// options bag, so the published declaration described a call that does not exist. Consumers + /// type-check against these declarations, so the disagreement surfaces as a compile error in + /// their code rather than anywhere near this repository. + /// + [Fact] + public void ApiExportDeclaresEntryPointsWithTheSignatureTheGeneratorEmits() + { + var context = CreateEntryPointContext(); + + var projector = new TypeScriptApiProjector(context); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(EntryPointPackage, TestPackageVersion), + [EntryPointPackage]); + + var exported = Assert.Single( + model.Modules.SelectMany(module => module.Items), + item => item.Name == "startThing"); + + Assert.Equal( + "function startThing(client: AspireClientRpc, name: string, retries?: number): Promise", + exported.Declaration); + + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(context)["aspire.mts"]; + + Assert.Contains( + $"export async {exported.Declaration} {{", + generatedSource, + StringComparison.Ordinal); + } + + /// + /// Two assemblies whose names differ only in where their separators fall must not collapse to + /// the same options-interface qualifier. + /// + /// + /// The qualifier used to keep only letters and digits, so Contoso.Foo.Bar and + /// Contoso.FooBar both produced ContosoFooBar. A per-package export cannot see + /// that some other package would land on the same qualifier, so it has no opportunity to + /// disambiguate the way full generation could; the two packages would each emit a + /// ContosoFooBarRunAsEmulatorOptions with different members and aspire.dev would + /// concatenate them into a duplicate declaration that does not compile. Encoding the separator + /// instead of dropping it makes the qualifier injective, which is what removes the possibility. + /// + [Fact] + public void OptionsInterfaceQualifiersDistinguishAssembliesThatDifferOnlyBySeparatorPlacement() + { + var dotted = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.Foo.Bar"); + var joined = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.FooBar"); + + Assert.NotEqual(dotted, joined); + Assert.Equal("Contoso_Foo_BarRunAsEmulatorOptions", dotted); + Assert.Equal("Contoso_FooBarRunAsEmulatorOptions", joined); + } + + /// + /// An assembly name that starts with a digit still yields a parseable TypeScript identifier. + /// + /// + /// Assembly names may begin with a digit -- 3rdParty.Aspire is legal -- but TypeScript + /// identifiers may not, so the unguarded qualifier emitted + /// interface 3rdPartyAspireRunAsEmulatorOptions, which is a syntax error rather than a + /// naming inconvenience. The escape cannot alias a name that already begins with an underscore + /// because a literal underscore encodes as a doubled one. + /// + [Fact] + public void OptionsInterfaceQualifiersEscapeAssemblyNamesThatStartWithADigit() + { + var name = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "3rdParty.Aspire"); + + Assert.Equal("_3rdParty_AspireRunAsEmulatorOptions", name); + Assert.True(name[0] is '_' or '$' || char.IsLetter(name[0]), $"'{name}' is not a valid TypeScript identifier."); + Assert.NotEqual(name, TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "_3rdParty.Aspire")); + } + /// /// An options interface is documented by, and keyed to, the assembly whose capability produced /// it rather than the package the export was requested for. @@ -2586,15 +2668,15 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() documentedOptions, item => { - Assert.Equal("AzureEventHubsRunAsEmulatorOptions", item.Name); + Assert.Equal("Azure_EventHubsRunAsEmulatorOptions", item.Name); Assert.Equal(CollisionPackageA, item.OwningAssemblyName); }); var serviceBusDeclaration = Assert.Single( model.Declarations, - declaration => declaration.Content.Contains("AzureServiceBusRunAsEmulatorOptions", StringComparison.Ordinal)); + declaration => declaration.Content.Contains("Azure_ServiceBusRunAsEmulatorOptions", StringComparison.Ordinal)); - Assert.Equal($"{CollisionPackageB}:options:AzureServiceBusRunAsEmulatorOptions", serviceBusDeclaration.Id); + Assert.Equal($"{CollisionPackageB}:options:Azure_ServiceBusRunAsEmulatorOptions", serviceBusDeclaration.Id); Assert.Equal(CollisionPackageB, serviceBusDeclaration.OwningAssemblyName); } @@ -2612,7 +2694,7 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() /// Both directions fail under the old scheme, but at different assertions, and that asymmetry /// is why the body comparison is here. Event Hubs was scanned first and kept the unsuffixed /// base name, so it fails only on the name: it produced RunAsEmulatorOptions rather than - /// AzureEventHubsRunAsEmulatorOptions. Service Bus lost that draw during full generation + /// Azure_EventHubsRunAsEmulatorOptions. Service Bus lost that draw during full generation /// and was suffixed there while its own single-package export was not, so it disagreed about /// the interface itself. Checking only that the exported name appears among the generated names /// would have missed it, because the name did appear -- it just belonged to Event Hubs. The old @@ -2623,8 +2705,8 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() /// /// [Theory] - [InlineData(CollisionPackageA, "AzureEventHubsRunAsEmulatorOptions")] - [InlineData(CollisionPackageB, "AzureServiceBusRunAsEmulatorOptions")] + [InlineData(CollisionPackageA, "Azure_EventHubsRunAsEmulatorOptions")] + [InlineData(CollisionPackageB, "Azure_ServiceBusRunAsEmulatorOptions")] public void ApiExportNamesACollidingOptionsInterfaceTheWayGenerationDoes(string packageName, string expectedInterfaceName) { var fullContext = CreateEmulatorCollisionContext(); @@ -2665,6 +2747,52 @@ public void ApiExportNamesACollidingOptionsInterfaceTheWayGenerationDoes(string /// Action<IResourceBuilder<T>> for different T, so their options /// interfaces cannot be merged. The capabilities here are synthetic; only the shape matters. /// + private const string EntryPointPackage = "Aspire.Hosting.Contoso.EntryPoints"; + + /// + /// Builds a context holding a single entry-point capability: one with no target type, so it is + /// emitted as a free function rather than as a member of a builder interface. + /// + private static AtsContext CreateEntryPointContext() + { + var capability = new AtsCapabilityInfo + { + CapabilityId = $"{EntryPointPackage}/startThing", + MethodName = "startThing", + Parameters = + [ + new AtsParameterInfo + { + Name = "name", + Type = new AtsTypeRef { TypeId = AtsConstants.String, Category = AtsTypeCategory.Primitive } + }, + new AtsParameterInfo + { + Name = "retries", + Type = new AtsTypeRef { TypeId = AtsConstants.Number, Category = AtsTypeCategory.Primitive }, + IsOptional = true + } + ], + ReturnType = new AtsTypeRef { TypeId = AtsConstants.Void, Category = AtsTypeCategory.Primitive }, + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.Method + }; + + return new AtsContext + { + Capabilities = [capability], + HandleTypes = [], + DtoTypes = [], + EnumTypes = [], + ExportedValues = [], + Diagnostics = [], + CapabilityExportingAssemblyNames = new Dictionary(StringComparer.Ordinal) + { + [capability.CapabilityId] = EntryPointPackage + } + }; + } + private static AtsContext CreateEmulatorCollisionContext(bool includeEventHubs = true, bool includeServiceBus = true) { static AtsTypeInfo Resource(string packageName, string typeName) => new() diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts index 20a8714cea9..bce90e5304f 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts @@ -172,47 +172,47 @@ export namespace TestConfigs { // Options Interfaces // ============================================================================ -export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions { +export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions { databaseName?: string; } -export interface CodeGenerationTypeScriptTestsAddTestRedisOptions { +export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions { port?: number; } -export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions { +export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions { +export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { +export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions { +export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions { +export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions { +export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions { +export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -export interface CodeGenerationTypeScriptTestsWithPersistenceOptions { +export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions { mode?: TestPersistenceMode; } @@ -667,7 +667,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -679,7 +679,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addTestRedis(name, options)), this._client); } @@ -769,7 +769,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -784,7 +784,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -807,7 +807,7 @@ export interface TestDatabaseResource { * Adds a data volume * @param options Additional options. */ - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestDatabaseResourcePromise; + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestDatabaseResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestDatabaseResourcePromise; /** Adds a categorized label to the resource */ @@ -820,12 +820,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -837,7 +837,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withOptionalString(options)), this._client); } @@ -1380,7 +1380,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -1420,7 +1420,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestDatabaseResourcePromise { + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -1440,11 +1440,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -1471,17 +1471,17 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1502,7 +1502,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1529,21 +1529,21 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1556,12 +1556,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1576,17 +1576,17 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1607,7 +1607,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1634,21 +1634,21 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1661,12 +1661,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1700,7 +1700,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -1720,7 +1720,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -1741,7 +1741,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -1880,7 +1880,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2056,7 +2056,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { + async getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2089,7 +2089,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2137,7 +2137,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -2219,7 +2219,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2241,7 +2241,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -2296,15 +2296,15 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return this._promise.then(onfulfilled, onrejected); } - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -2340,7 +2340,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -2388,7 +2388,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -2396,7 +2396,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -2404,7 +2404,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -2424,11 +2424,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -2452,7 +2452,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2467,7 +2467,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2500,12 +2500,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2517,7 +2517,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2532,7 +2532,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2565,12 +2565,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2602,7 +2602,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -2708,7 +2708,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2951,7 +2951,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2973,7 +2973,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3028,7 +3028,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3052,7 +3052,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3112,11 +3112,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -3140,7 +3140,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3153,7 +3153,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3182,12 +3182,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3199,7 +3199,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3212,7 +3212,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3241,12 +3241,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3278,7 +3278,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -3364,7 +3364,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -3577,7 +3577,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -3599,7 +3599,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3654,7 +3654,7 @@ class ResourcePromiseImpl implements ResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3674,7 +3674,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3726,11 +3726,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index aae67a2f3a7..074aa266e99 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -1,12 +1,12 @@ // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource export interface CSharpAppResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -20,21 +20,21 @@ export interface CSharpAppResource { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise export interface CSharpAppResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -48,20 +48,20 @@ export interface CSharpAppResourcePromise { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource export interface ContainerRegistryResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -74,20 +74,20 @@ export interface ContainerRegistryResource { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise export interface ContainerRegistryResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -100,21 +100,21 @@ export interface ContainerRegistryResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource export interface ContainerResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -128,21 +128,21 @@ export interface ContainerResource { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise export interface ContainerResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -156,33 +156,33 @@ export interface ContainerResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder export interface DistributedApplicationBuilder { - addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise export interface DistributedApplicationBuilderPromise { - addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource export interface DotnetToolResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -196,21 +196,21 @@ export interface DotnetToolResource { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise export interface DotnetToolResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -224,21 +224,21 @@ export interface DotnetToolResourcePromise { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource export interface ExecutableResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -252,21 +252,21 @@ export interface ExecutableResource { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise export interface ExecutableResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -280,20 +280,20 @@ export interface ExecutableResourcePromise { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource export interface ExternalServiceResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -306,20 +306,20 @@ export interface ExternalServiceResource { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise export interface ExternalServiceResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -332,20 +332,20 @@ export interface ExternalServiceResourcePromise { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource export interface ParameterResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -358,20 +358,20 @@ export interface ParameterResource { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise export interface ParameterResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -384,21 +384,21 @@ export interface ParameterResourcePromise { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource export interface ProjectResource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -412,21 +412,21 @@ export interface ProjectResource { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise export interface ProjectResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -440,20 +440,20 @@ export interface ProjectResourcePromise { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource export interface Resource { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -466,20 +466,20 @@ export interface Resource { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise export interface ResourcePromise { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -492,8 +492,8 @@ export interface ResourcePromise { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } @@ -586,13 +586,13 @@ export interface TestCollectionContextPromise extends PromiseLike Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -606,21 +606,21 @@ export interface TestDatabaseResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise export interface TestDatabaseResourcePromise extends PromiseLike { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; withConfig(config: TestConfigDto): TestDatabaseResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -634,8 +634,8 @@ export interface TestDatabaseResourcePromise extends PromiseLike>; getMetadata(): Promise>; @@ -669,7 +669,7 @@ export interface TestRedisResource extends ResourceBuilderBase { withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -681,26 +681,26 @@ export interface TestRedisResource extends ResourceBuilderBase { withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise export interface TestRedisResourcePromise extends PromiseLike { - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; withConfig(config: TestConfigDto): TestRedisResourcePromise; getTags(): Promise>; getMetadata(): Promise>; @@ -709,7 +709,7 @@ export interface TestRedisResourcePromise extends PromiseLike withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -721,17 +721,17 @@ export interface TestRedisResourcePromise extends PromiseLike withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } @@ -758,13 +758,13 @@ export interface TestResourceContextPromise extends PromiseLike Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -779,21 +779,21 @@ export interface TestVaultResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise export interface TestVaultResourcePromise extends PromiseLike { - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; withConfig(config: TestConfigDto): TestVaultResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -808,63 +808,63 @@ export interface TestVaultResourcePromise extends PromiseLike withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions -export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions +export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions { databaseName?: string; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestRedisOptions -export interface CodeGenerationTypeScriptTestsAddTestRedisOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestRedisOptions +export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions { port?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsGetStatusAsyncOptions -export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions +export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions -export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions +export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithDataVolumeOptions -export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithDataVolumeOptions +export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingOptions -export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions +export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions -export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions +export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions -export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions +export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalStringOptions -export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalStringOptions +export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithPersistenceOptions -export interface CodeGenerationTypeScriptTestsWithPersistenceOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithPersistenceOptions +export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions { mode?: TestPersistenceMode; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index 97a3f422e94..ffd306cc5ff 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -24,14 +24,14 @@ "id": "method:CSharpAppResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "CSharpAppResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -120,14 +120,14 @@ "id": "method:CSharpAppResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "CSharpAppResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -364,7 +364,7 @@ "id": "method:CSharpAppResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging", @@ -376,7 +376,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -385,7 +385,7 @@ "id": "method:CSharpAppResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging with file path", @@ -402,7 +402,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -491,14 +491,14 @@ "id": "method:ContainerRegistryResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerRegistryResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -571,14 +571,14 @@ "id": "method:ContainerRegistryResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -799,7 +799,7 @@ "id": "method:ContainerRegistryResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging", @@ -811,7 +811,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -820,7 +820,7 @@ "id": "method:ContainerRegistryResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging with file path", @@ -837,7 +837,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -927,14 +927,14 @@ "id": "method:ContainerResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -1023,14 +1023,14 @@ "id": "method:ContainerResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -1267,7 +1267,7 @@ "id": "method:ContainerResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging", @@ -1279,7 +1279,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -1288,7 +1288,7 @@ "id": "method:ContainerResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging with file path", @@ -1305,7 +1305,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -1392,7 +1392,7 @@ "id": "method:DistributedApplicationBuilder.addTestRedis", "kind": "method", "name": "addTestRedis", - "declaration": "addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise", + "declaration": "addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestRedis", "returnType": "TestRedisResourcePromise", "summary": "Adds a test Redis resource from ATS documentation.", @@ -1405,7 +1405,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsAddTestRedisOptions", + "type": "CodeGeneration_TypeScript_TestsAddTestRedisOptions", "optional": true } ] @@ -1443,14 +1443,14 @@ "id": "method:DotnetToolResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "DotnetToolResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -1539,14 +1539,14 @@ "id": "method:DotnetToolResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "DotnetToolResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -1783,7 +1783,7 @@ "id": "method:DotnetToolResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging", @@ -1795,7 +1795,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -1804,7 +1804,7 @@ "id": "method:DotnetToolResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging with file path", @@ -1821,7 +1821,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -1912,14 +1912,14 @@ "id": "method:ExecutableResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExecutableResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -2008,14 +2008,14 @@ "id": "method:ExecutableResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExecutableResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -2252,7 +2252,7 @@ "id": "method:ExecutableResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging", @@ -2264,7 +2264,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -2273,7 +2273,7 @@ "id": "method:ExecutableResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging with file path", @@ -2290,7 +2290,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -2379,14 +2379,14 @@ "id": "method:ExternalServiceResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExternalServiceResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -2459,14 +2459,14 @@ "id": "method:ExternalServiceResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExternalServiceResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -2687,7 +2687,7 @@ "id": "method:ExternalServiceResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging", @@ -2699,7 +2699,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -2708,7 +2708,7 @@ "id": "method:ExternalServiceResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging with file path", @@ -2725,7 +2725,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -2815,14 +2815,14 @@ "id": "method:ParameterResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ParameterResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -2895,14 +2895,14 @@ "id": "method:ParameterResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ParameterResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -3123,7 +3123,7 @@ "id": "method:ParameterResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging", @@ -3135,7 +3135,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -3144,7 +3144,7 @@ "id": "method:ParameterResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging with file path", @@ -3161,7 +3161,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -3251,14 +3251,14 @@ "id": "method:ProjectResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ProjectResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -3347,14 +3347,14 @@ "id": "method:ProjectResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ProjectResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -3591,7 +3591,7 @@ "id": "method:ProjectResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging", @@ -3603,7 +3603,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -3612,7 +3612,7 @@ "id": "method:ProjectResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging with file path", @@ -3629,7 +3629,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -3719,14 +3719,14 @@ "id": "method:Resource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -3799,14 +3799,14 @@ "id": "method:Resource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -4027,7 +4027,7 @@ "id": "method:Resource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ResourcePromise", "summary": "Configures resource logging", @@ -4039,7 +4039,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -4048,7 +4048,7 @@ "id": "method:Resource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ResourcePromise", "summary": "Configures resource logging with file path", @@ -4065,7 +4065,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -4473,14 +4473,14 @@ "id": "method:TestDatabaseResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestDatabaseResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -4569,14 +4569,14 @@ "id": "method:TestDatabaseResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestDatabaseResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -4813,7 +4813,7 @@ "id": "method:TestDatabaseResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging", @@ -4825,7 +4825,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -4834,7 +4834,7 @@ "id": "method:TestDatabaseResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging with file path", @@ -4851,7 +4851,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -4996,7 +4996,7 @@ "id": "method:TestRedisResource.addTestChildDatabase", "kind": "method", "name": "addTestChildDatabase", - "declaration": "addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise", + "declaration": "addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestChildDatabase", "returnType": "TestDatabaseResourcePromise", "summary": "Adds a child database to a test Redis resource", @@ -5009,7 +5009,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", + "type": "CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", "optional": true } ] @@ -5018,14 +5018,14 @@ "id": "method:TestRedisResource.withPersistence", "kind": "method", "name": "withPersistence", - "declaration": "withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise", + "declaration": "withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withPersistence", "returnType": "TestRedisResourcePromise", "summary": "Configures the Redis resource with persistence", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithPersistenceOptions", + "type": "CodeGeneration_TypeScript_TestsWithPersistenceOptions", "optional": true } ] @@ -5034,14 +5034,14 @@ "id": "method:TestRedisResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestRedisResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -5164,14 +5164,14 @@ "id": "method:TestRedisResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestRedisResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -5349,14 +5349,14 @@ "id": "method:TestRedisResource.getStatusAsync", "kind": "method", "name": "getStatusAsync", - "declaration": "getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise\u003Cstring\u003E", + "declaration": "getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getStatusAsync", "returnType": "Promise\u003Cstring\u003E", "summary": "Gets the status of the resource asynchronously", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsGetStatusAsyncOptions", + "type": "CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", "optional": true } ] @@ -5381,7 +5381,7 @@ "id": "method:TestRedisResource.waitForReadyAsync", "kind": "method", "name": "waitForReadyAsync", - "declaration": "waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", + "declaration": "waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync", "returnType": "Promise\u003Cboolean\u003E", "summary": "Waits for the resource to be ready", @@ -5393,7 +5393,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", + "type": "CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", "optional": true } ] @@ -5418,14 +5418,14 @@ "id": "method:TestRedisResource.withDataVolume", "kind": "method", "name": "withDataVolume", - "declaration": "withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise", + "declaration": "withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDataVolume", "returnType": "TestRedisResourcePromise", "summary": "Adds a data volume with persistence", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithDataVolumeOptions", + "type": "CodeGeneration_TypeScript_TestsWithDataVolumeOptions", "optional": true } ] @@ -5518,7 +5518,7 @@ "id": "method:TestRedisResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging", @@ -5530,7 +5530,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -5539,7 +5539,7 @@ "id": "method:TestRedisResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging with file path", @@ -5556,7 +5556,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -5704,14 +5704,14 @@ "id": "method:TestVaultResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise", + "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestVaultResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "optional": true } ] @@ -5800,14 +5800,14 @@ "id": "method:TestVaultResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise", + "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestVaultResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -6060,7 +6060,7 @@ "id": "method:TestVaultResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging", @@ -6072,7 +6072,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "optional": true } ] @@ -6081,7 +6081,7 @@ "id": "method:TestVaultResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging with file path", @@ -6098,7 +6098,7 @@ }, { "name": "options", - "type": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -6173,15 +6173,15 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", + "id": "options:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", + "name": "CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions.databaseName", + "id": "property:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions.databaseName", "kind": "property", "name": "databaseName", "declaration": "databaseName?: string" @@ -6189,15 +6189,15 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsAddTestRedisOptions", + "id": "options:CodeGeneration_TypeScript_TestsAddTestRedisOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsAddTestRedisOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsAddTestRedisOptions", + "name": "CodeGeneration_TypeScript_TestsAddTestRedisOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsAddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsAddTestRedisOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsAddTestRedisOptions.port", + "id": "property:CodeGeneration_TypeScript_TestsAddTestRedisOptions.port", "kind": "property", "name": "port", "declaration": "port?: number" @@ -6205,15 +6205,15 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsGetStatusAsyncOptions", + "id": "options:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsGetStatusAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsGetStatusAsyncOptions", + "name": "CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsGetStatusAsyncOptions.cancellationToken", + "id": "property:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions.cancellationToken", "kind": "property", "name": "cancellationToken", "declaration": "cancellationToken?: AbortSignal | CancellationToken" @@ -6221,15 +6221,15 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", + "id": "options:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", + "name": "CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions.cancellationToken", + "id": "property:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions.cancellationToken", "kind": "property", "name": "cancellationToken", "declaration": "cancellationToken?: AbortSignal | CancellationToken" @@ -6237,21 +6237,21 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsWithDataVolumeOptions", + "id": "options:CodeGeneration_TypeScript_TestsWithDataVolumeOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsWithDataVolumeOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithDataVolumeOptions", + "name": "CodeGeneration_TypeScript_TestsWithDataVolumeOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsWithDataVolumeOptions.name", + "id": "property:CodeGeneration_TypeScript_TestsWithDataVolumeOptions.name", "kind": "property", "name": "name", "declaration": "name?: string" }, { - "id": "property:CodeGenerationTypeScriptTestsWithDataVolumeOptions.isReadOnly", + "id": "property:CodeGeneration_TypeScript_TestsWithDataVolumeOptions.isReadOnly", "kind": "property", "name": "isReadOnly", "declaration": "isReadOnly?: boolean" @@ -6259,21 +6259,21 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "id": "options:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsWithMergeLoggingOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "name": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingOptions.enableConsole", + "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingOptions.maxFiles", + "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6281,21 +6281,21 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "id": "options:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "name": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions.enableConsole", + "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions.maxFiles", + "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6303,15 +6303,15 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "id": "options:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "name": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions.callback", + "id": "property:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions.callback", "kind": "property", "name": "callback", "declaration": "callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E" @@ -6319,21 +6319,21 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "id": "options:CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsWithOptionalStringOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "name": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsWithOptionalStringOptions.value", + "id": "property:CodeGeneration_TypeScript_TestsWithOptionalStringOptions.value", "kind": "property", "name": "value", "declaration": "value?: string" }, { - "id": "property:CodeGenerationTypeScriptTestsWithOptionalStringOptions.enabled", + "id": "property:CodeGeneration_TypeScript_TestsWithOptionalStringOptions.enabled", "kind": "property", "name": "enabled", "declaration": "enabled?: boolean" @@ -6341,15 +6341,15 @@ ] }, { - "id": "options:CodeGenerationTypeScriptTestsWithPersistenceOptions", + "id": "options:CodeGeneration_TypeScript_TestsWithPersistenceOptions", "kind": "options", - "name": "CodeGenerationTypeScriptTestsWithPersistenceOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGenerationTypeScriptTestsWithPersistenceOptions", + "name": "CodeGeneration_TypeScript_TestsWithPersistenceOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGenerationTypeScriptTestsWithPersistenceOptions", + "declaration": "export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions", "members": [ { - "id": "property:CodeGenerationTypeScriptTestsWithPersistenceOptions.mode", + "id": "property:CodeGeneration_TypeScript_TestsWithPersistenceOptions.mode", "kind": "property", "name": "mode", "declaration": "mode?: TestPersistenceMode" @@ -6363,102 +6363,102 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Resource {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface Resource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourcePromise {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface ResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString", @@ -6528,12 +6528,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext", @@ -6548,12 +6548,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", @@ -6568,62 +6568,62 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions {\n databaseName?: string;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions {\n databaseName?: string;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsAddTestRedisOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsAddTestRedisOptions {\n port?: number;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions {\n port?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsGetStatusAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithDataVolumeOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalCallbackOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithOptionalStringOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGenerationTypeScriptTestsWithPersistenceOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGenerationTypeScriptTestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" + "content": "export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" }, { "id": "Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle", diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts index 6bfef538a6d..6c4219b9c08 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts @@ -1537,47 +1537,47 @@ export interface BuildOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions { +export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions { databaseName?: string; } -export interface CodeGenerationTypeScriptTestsAddTestRedisOptions { +export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions { port?: number; } -export interface CodeGenerationTypeScriptTestsGetStatusAsyncOptions { +export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions { +export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { +export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface CodeGenerationTypeScriptTestsWithMergeLoggingOptions { +export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions { +export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGenerationTypeScriptTestsWithOptionalCallbackOptions { +export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -export interface CodeGenerationTypeScriptTestsWithOptionalStringOptions { +export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -export interface CodeGenerationTypeScriptTestsWithPersistenceOptions { +export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions { mode?: TestPersistenceMode; } @@ -10946,7 +10946,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -11167,7 +11167,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addHealthCheck(name, check)), this._client); } - addTestRedis(name: string, options?: CodeGenerationTypeScriptTestsAddTestRedisOptions): TestRedisResourcePromise { + addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.addTestRedis(name, options)), this._client); } @@ -14688,7 +14688,7 @@ export interface ContainerRegistryResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; /** Sets the created timestamp */ @@ -14701,7 +14701,7 @@ export interface ContainerRegistryResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; /** Configures with nested DTO */ @@ -14730,12 +14730,12 @@ export interface ContainerRegistryResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; /** Configures a route with middleware */ @@ -15005,7 +15005,7 @@ export interface ContainerRegistryResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerRegistryResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -16508,7 +16508,7 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -16560,11 +16560,11 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerRegistryResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -17335,7 +17335,7 @@ export interface ContainerResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -17350,7 +17350,7 @@ export interface ContainerResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -17381,12 +17381,12 @@ export interface ContainerResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -18144,7 +18144,7 @@ export interface ContainerResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -18159,7 +18159,7 @@ export interface ContainerResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -18190,12 +18190,12 @@ export interface ContainerResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -20543,7 +20543,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ContainerResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -20649,7 +20649,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise { const callback = options?.callback; return new ContainerResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -20877,7 +20877,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -20899,7 +20899,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -21318,7 +21318,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -21342,7 +21342,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -21398,11 +21398,11 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -21987,7 +21987,7 @@ export interface CSharpAppResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22002,7 +22002,7 @@ export interface CSharpAppResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22033,12 +22033,12 @@ export interface CSharpAppResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -22611,7 +22611,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22626,7 +22626,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22657,12 +22657,12 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -24569,7 +24569,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise { const value = options?.value; const enabled = options?.enabled; return new CSharpAppResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -24675,7 +24675,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { const callback = options?.callback; return new CSharpAppResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -24903,7 +24903,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -24925,7 +24925,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -25276,7 +25276,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -25300,7 +25300,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -25356,11 +25356,11 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -25967,7 +25967,7 @@ export interface DotnetToolResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): DotnetToolResourcePromise; /** Configures environment with callback (test version) */ @@ -25982,7 +25982,7 @@ export interface DotnetToolResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): DotnetToolResourcePromise; /** Configures with nested DTO */ @@ -26013,12 +26013,12 @@ export interface DotnetToolResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; /** Configures a route with middleware */ @@ -26613,7 +26613,7 @@ export interface DotnetToolResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): DotnetToolResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -29389,7 +29389,7 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): DotnetToolResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -29445,11 +29445,11 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): DotnetToolResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): DotnetToolResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -30030,7 +30030,7 @@ export interface ExecutableResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExecutableResourcePromise; /** Configures environment with callback (test version) */ @@ -30045,7 +30045,7 @@ export interface ExecutableResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExecutableResourcePromise; /** Configures with nested DTO */ @@ -30076,12 +30076,12 @@ export interface ExecutableResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; /** Configures a route with middleware */ @@ -30643,7 +30643,7 @@ export interface ExecutableResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExecutableResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -33291,7 +33291,7 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExecutableResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -33347,11 +33347,11 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExecutableResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExecutableResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -33638,7 +33638,7 @@ export interface ExternalServiceResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExternalServiceResourcePromise; /** Sets the created timestamp */ @@ -33651,7 +33651,7 @@ export interface ExternalServiceResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; /** Configures with nested DTO */ @@ -33680,12 +33680,12 @@ export interface ExternalServiceResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; /** Configures a route with middleware */ @@ -33960,7 +33960,7 @@ export interface ExternalServiceResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ExternalServiceResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -35491,7 +35491,7 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ExternalServiceResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -35543,11 +35543,11 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ExternalServiceResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -35843,7 +35843,7 @@ export interface ParameterResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -35856,7 +35856,7 @@ export interface ParameterResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -35885,12 +35885,12 @@ export interface ParameterResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -36173,7 +36173,7 @@ export interface ParameterResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -36186,7 +36186,7 @@ export interface ParameterResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -36215,12 +36215,12 @@ export interface ParameterResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -37182,7 +37182,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ParameterResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -37268,7 +37268,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise { const callback = options?.callback; return new ParameterResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -37481,7 +37481,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -37503,7 +37503,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -37706,7 +37706,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -37726,7 +37726,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -37778,11 +37778,11 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -38368,7 +38368,7 @@ export interface ProjectResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -38383,7 +38383,7 @@ export interface ProjectResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -38414,12 +38414,12 @@ export interface ProjectResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -38992,7 +38992,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -39007,7 +39007,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -39038,12 +39038,12 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -40951,7 +40951,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ProjectResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -41057,7 +41057,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise { const callback = options?.callback; return new ProjectResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -41285,7 +41285,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -41307,7 +41307,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -41658,7 +41658,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -41682,7 +41682,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -41738,11 +41738,11 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -42512,7 +42512,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -42527,7 +42527,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -42558,12 +42558,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -43321,7 +43321,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestDatabaseResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -46518,7 +46518,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -46574,11 +46574,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -47373,17 +47373,17 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -47404,7 +47404,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -47431,21 +47431,21 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -47458,12 +47458,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -48246,17 +48246,17 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -48277,7 +48277,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -48304,21 +48304,21 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -48331,12 +48331,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -50745,7 +50745,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -50765,7 +50765,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -50786,7 +50786,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -50925,7 +50925,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -51101,7 +51101,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { + async getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51134,7 +51134,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51182,7 +51182,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -51264,7 +51264,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -51286,7 +51286,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -51717,15 +51717,15 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - addTestChildDatabase(name: string, options?: CodeGenerationTypeScriptTestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: CodeGenerationTypeScriptTestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -51761,7 +51761,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -51809,7 +51809,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: CodeGenerationTypeScriptTestsGetStatusAsyncOptions): Promise { + getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -51817,7 +51817,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: CodeGenerationTypeScriptTestsWaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -51825,7 +51825,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: CodeGenerationTypeScriptTestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -51845,11 +51845,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -52619,7 +52619,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -52634,7 +52634,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -52667,12 +52667,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -53430,7 +53430,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -53445,7 +53445,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -53478,12 +53478,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -55830,7 +55830,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -55936,7 +55936,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -56179,7 +56179,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -56201,7 +56201,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -56620,7 +56620,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -56644,7 +56644,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -56704,11 +56704,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -57310,7 +57310,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57323,7 +57323,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57352,12 +57352,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -57627,7 +57627,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57640,7 +57640,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57669,12 +57669,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -58595,7 +58595,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -58681,7 +58681,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -58894,7 +58894,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -58916,7 +58916,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -59111,7 +59111,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGenerationTypeScriptTestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -59131,7 +59131,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGenerationTypeScriptTestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -59183,11 +59183,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGenerationTypeScriptTestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts index 0e65774a1fd..7209354cb02 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts @@ -1,4 +1,4 @@ -export interface CodeGenerationTypeScriptTestsWithDataVolumeOptions { +export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } \ No newline at end of file From e6cc066393db3270fc31925029693f6d5337bf9b Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sat, 8 Aug 2026 13:18:57 -0400 Subject: [PATCH 32/73] Fix package assembly scoping for API export Record package ownership in the integration probe manifest so sdk export can load and scope packages whose runtime assemblies do not match the package id, including packages with multiple assemblies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Projects/AppHostServerClosureSnapshots.cs | 4 +- .../AssemblyLoader.cs | 36 +++++- .../CodeGeneration/CodeGenerationService.cs | 66 +++++++---- .../NuGet/Commands/ManifestCommand.cs | 4 +- .../Commands/NuGetPackageAssetResolver.cs | 93 ++++++++++++--- src/Shared/IntegrationPackageProbeManifest.cs | 52 ++++++++- .../AssemblyLoaderTests.cs | 45 ++++++++ .../CodeGeneration/ApiReferenceExportTests.cs | 106 +++++++++++++++++- .../LayoutCommandTests.cs | 6 + 9 files changed, 363 insertions(+), 49 deletions(-) diff --git a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs index 9f40442407e..cdd39722f78 100644 --- a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs +++ b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs @@ -171,7 +171,9 @@ public IntegrationPackageProbeManifest CreatePackageProbeManifest() { Name = Path.GetFileNameWithoutExtension(entry.RelativePath), Culture = TryGetSatelliteCulture(entry), - Path = entry.SourcePath + Path = entry.SourcePath, + PackageId = entry.PackageId, + PackageVersion = entry.PackageVersion }); } diff --git a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs index 10edb0e8d43..c0f533031c5 100644 --- a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs +++ b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.Loader; using Aspire.Hosting.RemoteHost.CodeGeneration; @@ -69,6 +70,13 @@ public IReadOnlyList GetAssemblies() } } + public bool TryGetRuntimeAssemblyNamesForPackage( + string packageId, + [NotNullWhen(true)] + out string? canonicalPackageId, + out IReadOnlyList assemblyNames) + => _packageProbeManifest.TryGetRuntimeAssemblyNamesForPackage(packageId, out canonicalPackageId, out assemblyNames); + /// /// Snapshots the currently loaded ATS integration assemblies as /// records suitable for inclusion in a @@ -126,9 +134,33 @@ internal static IReadOnlyList GetAssemblyNamesToLoad( var assemblyNames = new List(); var seen = new HashSet(StringComparer.OrdinalIgnoreCase); - foreach (var name in configuration.GetSection("AtsAssemblies").Get() ?? []) + var configuredAssemblyNames = configuration.GetSection("AtsAssemblies").Get() ?? []; + foreach (var name in configuredAssemblyNames) { - if (!string.IsNullOrWhiteSpace(name) && seen.Add(name)) + if (string.IsNullOrWhiteSpace(name)) + { + continue; + } + + // For package-backed polyglot AppHosts, AtsAssemblies can name the NuGet package the + // user requested rather than every assembly inside that package. The probe manifest is + // the only data RemoteHost receives that preserves that package-to-assembly + // relationship, so expand configured package ids before auto-discovering transitive + // Aspire.Hosting assemblies. + if (packageProbeManifest?.TryGetRuntimeAssemblyNamesForPackage(name, out _, out var packageAssemblyNames) == true) + { + foreach (var packageAssemblyName in packageAssemblyNames) + { + if (seen.Add(packageAssemblyName)) + { + assemblyNames.Add(packageAssemblyName); + } + } + + continue; + } + + if (seen.Add(name)) { assemblyNames.Add(name); } diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index b98b7c7a743..6516cd7541e 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -316,29 +316,13 @@ public JsonElement ExportApi(string language, string packageName, string package // package. var fullContext = _atsContextFactory.GetContext(); - // A NuGet package id is case-insensitive - // (https://learn.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#package-identifiers) - // but the exported document records this string verbatim as the identity consumers key - // on, so `aspire.hosting.redis` would publish a document naming a package nobody looks - // up. The loaded assembly settles the spelling: every filter here treats the package id - // as an assembly name, so a package whose API is exportable at all is named in the - // context. One that is not has nothing to export under that id, and saying so beats - // publishing an empty document that claims to describe it. - if (!AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, packageName, out var canonicalPackageName)) - { - throw new InvalidOperationException( - $"'{packageName}' restored, but the scanned API surface contains nothing under that name, so there is no API to export under it. " + - "An API export is scoped by assembly name, so this is what a package whose assembly is named something other than " + - "its package id looks like from here."); - } - - packageName = canonicalPackageName; + var exportingAssemblyNames = ResolvePackageExportingAssemblyNames(fullContext, packageName, out var canonicalPackageName); var context = AtsContextFilter.FilterForApiExport( fullContext, - [packageName]); + exportingAssemblyNames); - var export = exporter.ExportApi(context, new ApiReferenceExportOptions(packageName, packageVersion, [packageName])); + var export = exporter.ExportApi(context, new ApiReferenceExportOptions(canonicalPackageName, packageVersion, exportingAssemblyNames)); _logger.LogDebug("<< exportApi({Language}, {PackageName}) completed in {ElapsedMs}ms", language, packageName, sw.ElapsedMilliseconds); @@ -359,6 +343,50 @@ public JsonElement ExportApi(string language, string packageName, string package } } + private IReadOnlyList ResolvePackageExportingAssemblyNames( + AtsContext fullContext, + string packageName, + out string canonicalPackageName) + { + if (_assemblyLoader.TryGetRuntimeAssemblyNamesForPackage(packageName, out var manifestPackageName, out var manifestAssemblyNames)) + { + var exportingAssemblyNames = new List(manifestAssemblyNames.Count); + foreach (var assemblyName in manifestAssemblyNames) + { + if (AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, assemblyName, out var canonicalAssemblyName)) + { + exportingAssemblyNames.Add(canonicalAssemblyName); + } + } + + if (exportingAssemblyNames.Count == 0) + { + throw new InvalidOperationException( + $"'{packageName}' restored, but none of its runtime assemblies reached the scanned API surface, so there is no API to export under it."); + } + + canonicalPackageName = manifestPackageName; + return exportingAssemblyNames; + } + + // A NuGet package id is case-insensitive + // (https://learn.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#package-identifiers) + // but the exported document records this string verbatim as the identity consumers key + // on, so `aspire.hosting.redis` would publish a document naming a package nobody looks + // up. For local project references and older probe manifests we do not have package-to- + // assembly metadata, so the loaded assembly settles the spelling as before. + if (!AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, packageName, out var canonicalAssemblyNameFromContext)) + { + throw new InvalidOperationException( + $"'{packageName}' restored, but the scanned API surface contains nothing under that name, so there is no API to export under it. " + + "An API export is scoped by assembly name, so this is what a package whose assembly is named something other than " + + "its package id looks like from here."); + } + + canonicalPackageName = canonicalAssemblyNameFromContext; + return [canonicalAssemblyNameFromContext]; + } + private string BuildApiExportLanguageList() { var exportable = _resolver.GetSupportedLanguages() diff --git a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs index a027af5a608..b30c1f4916f 100644 --- a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs +++ b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs @@ -138,7 +138,9 @@ internal static IntegrationPackageProbeManifest CreateManifest(IEnumerable Assets, int SkippedCount) Resol // Synthetic restores can leave the base lib assembly in the target even when the package // contains a compatible portable runtime asset. Prefer the runtime asset for probing. var runtimeAssemblyOverrides = GetRuntimeAssemblyOverrides(packageLibrary, targetFramework, runtimeIdentifiers); - AddRuntimeAssemblies(assets, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides); - AddRuntimeTargets(assets, library.RuntimeTargets, packagePath); - AddResourceAssemblies(assets, library.ResourceAssemblies, packagePath); - AddNativeLibraries(assets, library.NativeLibraries, packagePath); + AddRuntimeAssemblies(assets, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides, libraryName, libraryVersion); + AddRuntimeTargets(assets, library.RuntimeTargets, packagePath, libraryName, libraryVersion); + AddResourceAssemblies(assets, library.ResourceAssemblies, packagePath, libraryName, libraryVersion); + AddNativeLibraries(assets, library.NativeLibraries, packagePath, libraryName, libraryVersion); return (assets, 0); } @@ -163,7 +167,9 @@ private static void AddRuntimeAssemblies( List assets, IEnumerable runtimeAssemblies, string packagePath, - IReadOnlyDictionary runtimeAssemblyOverrides) + IReadOnlyDictionary runtimeAssemblyOverrides, + string packageId, + string packageVersion) { foreach (var runtimeAssembly in runtimeAssemblies) { @@ -176,18 +182,20 @@ private static void AddRuntimeAssemblies( if (!relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase) && runtimeAssemblyOverrides.TryGetValue(GetFileName(relativePath), out var overridePath)) { - AddRuntimeAssembly(assets, packagePath, overridePath); + AddRuntimeAssembly(assets, packagePath, overridePath, packageId, packageVersion); continue; } - AddRuntimeAssembly(assets, packagePath, relativePath); + AddRuntimeAssembly(assets, packagePath, relativePath, packageId, packageVersion); } } private static void AddRuntimeAssembly( List assets, string packagePath, - string relativePath) + string relativePath, + string packageId, + string packageVersion) { var sourcePath = Path.Combine(packagePath, relativePath.Replace('/', Path.DirectorySeparatorChar)); if (!File.Exists(sourcePath)) @@ -196,17 +204,38 @@ private static void AddRuntimeAssembly( } var fileName = Path.GetFileName(sourcePath); - AddAsset(assets, sourcePath, fileName, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); + AddAsset( + assets, + sourcePath, + fileName, + isManagedAssembly: IsManagedAssembly(sourcePath), + isNativeLibrary: false, + packageId: packageId, + packageVersion: packageVersion); if (relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase)) { - AddAsset(assets, sourcePath, relativePath, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); + AddAsset( + assets, + sourcePath, + relativePath, + isManagedAssembly: IsManagedAssembly(sourcePath), + isNativeLibrary: false, + packageId: packageId, + packageVersion: packageVersion); } var xmlSourcePath = Path.ChangeExtension(sourcePath, ".xml"); if (File.Exists(xmlSourcePath)) { - AddAsset(assets, xmlSourcePath, Path.ChangeExtension(fileName, ".xml"), isManagedAssembly: false, isNativeLibrary: false); + AddAsset( + assets, + xmlSourcePath, + Path.ChangeExtension(fileName, ".xml"), + isManagedAssembly: false, + isNativeLibrary: false, + packageId: packageId, + packageVersion: packageVersion); } } @@ -310,7 +339,9 @@ private static string GetFileName(string path) private static void AddRuntimeTargets( List assets, IEnumerable runtimeTargets, - string packagePath) + string packagePath, + string packageId, + string packageVersion) { foreach (var runtimeTarget in runtimeTargets) { @@ -330,14 +361,18 @@ private static void AddRuntimeTargets( sourcePath, runtimeTarget.Path, isManagedAssembly: string.Equals(runtimeTarget.AssetType, "runtime", StringComparison.OrdinalIgnoreCase) && IsManagedAssembly(sourcePath), - isNativeLibrary: string.Equals(runtimeTarget.AssetType, "native", StringComparison.OrdinalIgnoreCase)); + isNativeLibrary: string.Equals(runtimeTarget.AssetType, "native", StringComparison.OrdinalIgnoreCase), + packageId: packageId, + packageVersion: packageVersion); } } private static void AddResourceAssemblies( List assets, IEnumerable resourceAssemblies, - string packagePath) + string packagePath, + string packageId, + string packageVersion) { foreach (var resourceAssembly in resourceAssemblies) { @@ -367,6 +402,8 @@ private static void AddResourceAssemblies( Path.Combine(locale, Path.GetFileName(sourcePath)), isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false, + packageId: packageId, + packageVersion: packageVersion, culture: locale); } } @@ -374,7 +411,9 @@ private static void AddResourceAssemblies( private static void AddNativeLibraries( List assets, IEnumerable nativeLibraries, - string packagePath) + string packagePath, + string packageId, + string packageVersion) { foreach (var nativeLib in nativeLibraries) { @@ -389,8 +428,22 @@ private static void AddNativeLibraries( continue; } - AddAsset(assets, sourcePath, Path.GetFileName(sourcePath), isManagedAssembly: false, isNativeLibrary: true); - AddAsset(assets, sourcePath, nativeLib.Path, isManagedAssembly: false, isNativeLibrary: true); + AddAsset( + assets, + sourcePath, + Path.GetFileName(sourcePath), + isManagedAssembly: false, + isNativeLibrary: true, + packageId: packageId, + packageVersion: packageVersion); + AddAsset( + assets, + sourcePath, + nativeLib.Path, + isManagedAssembly: false, + isNativeLibrary: true, + packageId: packageId, + packageVersion: packageVersion); } } @@ -400,6 +453,8 @@ private static void AddAsset( string relativePath, bool isManagedAssembly, bool isNativeLibrary, + string packageId, + string packageVersion, string? culture = null) { assets.Add(new NuGetPackageAsset @@ -408,7 +463,9 @@ private static void AddAsset( RelativePath = NormalizeRelativePath(relativePath), IsManagedAssembly = isManagedAssembly, IsNativeLibrary = isNativeLibrary, - Culture = culture + Culture = culture, + PackageId = packageId, + PackageVersion = packageVersion }); } diff --git a/src/Shared/IntegrationPackageProbeManifest.cs b/src/Shared/IntegrationPackageProbeManifest.cs index 24b8fa64743..e3a57ea8416 100644 --- a/src/Shared/IntegrationPackageProbeManifest.cs +++ b/src/Shared/IntegrationPackageProbeManifest.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; using System.Text.Json; @@ -50,7 +51,9 @@ public static IntegrationPackageProbeManifest Create( { Name = NormalizeRequiredValue(assembly.Name, "managedAssemblies[].name"), Culture = NormalizeCulture(assembly.Culture), - Path = NormalizeRequiredValue(assembly.Path, "managedAssemblies[].path") + Path = NormalizeRequiredValue(assembly.Path, "managedAssemblies[].path"), + PackageId = NormalizeOptionalValue(assembly.PackageId), + PackageVersion = NormalizeOptionalValue(assembly.PackageVersion) }; managedLookup.TryAdd( @@ -142,6 +145,14 @@ public static Task WriteAsync( { writer.WriteString("culture", managedAssembly.Culture); } + if (managedAssembly.PackageId is not null) + { + writer.WriteString("packageId", managedAssembly.PackageId); + } + if (managedAssembly.PackageVersion is not null) + { + writer.WriteString("packageVersion", managedAssembly.PackageVersion); + } writer.WriteString("path", managedAssembly.Path); writer.WriteEndObject(); } @@ -177,6 +188,32 @@ public static Task WriteAsync( : null; } + public bool TryGetRuntimeAssemblyNamesForPackage( + string packageId, + [NotNullWhen(true)] out string? canonicalPackageId, + out IReadOnlyList assemblyNames) + { + ArgumentException.ThrowIfNullOrWhiteSpace(packageId); + + var names = new SortedSet(StringComparer.OrdinalIgnoreCase); + canonicalPackageId = null; + + foreach (var assembly in ManagedAssemblies) + { + if (assembly.Culture is not null || + !string.Equals(assembly.PackageId, packageId, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + canonicalPackageId ??= assembly.PackageId; + names.Add(assembly.Name); + } + + assemblyNames = names.ToList(); + return assemblyNames.Count > 0; + } + public IReadOnlyList GetNativeLibraryPaths(string unmanagedDllName) { var candidatePaths = new List(); @@ -370,6 +407,11 @@ private static string NormalizeRequiredValue(string? value, string propertyName) return value.Trim(); } + private static string? NormalizeOptionalValue(string? value) + { + return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); + } + private static IReadOnlyList ReadManagedAssemblies(JsonElement rootElement) { if (!rootElement.TryGetProperty("managedAssemblies", out var managedAssembliesElement) || @@ -385,7 +427,9 @@ private static IReadOnlyList ReadManagedAssem { Name = NormalizeRequiredValue(ReadStringProperty(element, "name"), "managedAssemblies[].name"), Culture = NormalizeCulture(ReadStringProperty(element, "culture", required: false)), - Path = NormalizeAndValidatePath(ReadStringProperty(element, "path"), "managedAssemblies[].path") + Path = NormalizeAndValidatePath(ReadStringProperty(element, "path"), "managedAssemblies[].path"), + PackageId = NormalizeOptionalValue(ReadStringProperty(element, "packageId", required: false)), + PackageVersion = NormalizeOptionalValue(ReadStringProperty(element, "packageVersion", required: false)) }); } @@ -445,6 +489,10 @@ internal sealed class IntegrationPackageManagedAssembly public string? Culture { get; init; } public required string Path { get; init; } + + public string? PackageId { get; init; } + + public string? PackageVersion { get; init; } } /// diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs index ee341e8423c..7dd692dc5bd 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs @@ -116,6 +116,51 @@ public void GetAssemblyNamesToLoad_AddsAutoDiscoveredAssembliesFromPackageProbeM assemblyNames); } + [Fact] + public void GetAssemblyNamesToLoad_AddsAssembliesOwnedByConfiguredPackageFromProbeManifest() + { + using var manifestDirectory = new TemporaryDirectory(); + using var packageAssemblyDirectory = new TemporaryDirectory(); + + var primaryAssemblyPath = System.IO.Path.Combine(packageAssemblyDirectory.Path, "Contoso.Hosting.dll"); + var secondaryAssemblyPath = System.IO.Path.Combine(packageAssemblyDirectory.Path, "Contoso.Hosting.Extras.dll"); + var dependencyAssemblyPath = System.IO.Path.Combine(packageAssemblyDirectory.Path, "Dependency.Hosting.dll"); + File.WriteAllText(primaryAssemblyPath, string.Empty); + File.WriteAllText(secondaryAssemblyPath, string.Empty); + File.WriteAllText(dependencyAssemblyPath, string.Empty); + + var manifestPath = System.IO.Path.Combine(manifestDirectory.Path, "integration-package-probe-manifest.json"); + WriteProbeManifest( + manifestPath, + managedAssemblies: + [ + new { Name = "Contoso.Hosting", Path = primaryAssemblyPath, PackageId = "Contoso.Aspire.MetaPackage", PackageVersion = "1.2.3" }, + new { Name = "Contoso.Hosting.Extras", Path = secondaryAssemblyPath, PackageId = "Contoso.Aspire.MetaPackage", PackageVersion = "1.2.3" }, + new { Name = "Dependency.Hosting", Path = dependencyAssemblyPath, PackageId = "Dependency.Hosting", PackageVersion = "4.5.6" } + ]); + + var probeManifest = IntegrationPackageProbeManifest.Load(manifestPath); + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["AtsAssemblies:0"] = "Contoso.Aspire.MetaPackage" + }) + .Build(); + + var assemblyNames = AssemblyLoader.GetAssemblyNamesToLoad( + configuration, + integrationLibsPath: null, + applicationBasePath: System.IO.Path.Combine(manifestDirectory.Path, "missing"), + packageProbeManifest: probeManifest); + + Assert.Equal( + [ + "Contoso.Hosting", + "Contoso.Hosting.Extras" + ], + assemblyNames); + } + [Fact] public void GetAssemblyNamesToLoad_CombinesPackageProbeManifestAndProjectLibs() { diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index d2a627e4a33..29c68f84955 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json; using Aspire.Hosting.RemoteHost.CodeGeneration; using Aspire.Hosting.RemoteHost.Diagnostics; using Aspire.TypeSystem; @@ -85,6 +86,50 @@ public void ExportApi_ScopesDocumentedItemsToRequestedPackage() Assert.Contains("Aspire.Hosting", declarationOwners); } + [Fact] + public void ExportApi_UsesPackageProbeManifestAssembliesForRequestedPackage() + { + using var manifestDirectory = new TemporaryDirectory(); + var manifestPath = Path.Combine(manifestDirectory.Path, "integration-package-probe-manifest.json"); + WriteProbeManifest( + manifestPath, + managedAssemblies: + [ + new + { + Name = "Aspire.Hosting", + Path = typeof(IDistributedApplicationBuilder).Assembly.Location, + PackageId = "Contoso.Aspire.MetaPackage", + PackageVersion = "1.2.3" + }, + new + { + Name = "Aspire.Hosting.Yarp", + Path = typeof(Yarp.YarpResource).Assembly.Location, + PackageId = "Contoso.Aspire.MetaPackage", + PackageVersion = "1.2.3" + } + ]); + var service = CreateCodeGenerationService(new Dictionary + { + ["AtsAssemblies:0"] = "Contoso.Aspire.MetaPackage", + ["ASPIRE_INTEGRATION_PROBE_MANIFEST_PATH"] = manifestPath + }); + + var export = service.ExportApi("TypeScript", "Contoso.Aspire.MetaPackage", "1.2.3"); + + Assert.Equal("Contoso.Aspire.MetaPackage", export.GetProperty("package").GetProperty("name").GetString()); + + var ownedItemOwners = export.GetProperty("modules").EnumerateArray() + .SelectMany(module => module.GetProperty("items").EnumerateArray()) + .Where(item => item.GetProperty("kind").GetString() != "augmentation") + .Select(item => item.GetProperty("owningAssembly").GetString()) + .ToHashSet(StringComparer.Ordinal); + + Assert.Contains("Aspire.Hosting", ownedItemOwners); + Assert.Contains("Aspire.Hosting.Yarp", ownedItemOwners); + } + [Fact] public void ExportApi_UnknownLanguage_ListsAvailableLanguages() { @@ -140,14 +185,26 @@ public void ExportApi_RequiresAuthentication() Assert.ThrowsAny(() => service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0")); } - private static CodeGenerationService CreateCodeGenerationService(bool authenticated = true) + private static CodeGenerationService CreateCodeGenerationService( + IReadOnlyDictionary? additionalConfiguration = null, + bool authenticated = true) { - var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary + var configurationValues = new Dictionary + { + ["AtsAssemblies:0"] = "Aspire.Hosting.CodeGeneration.Go", + ["AtsAssemblies:1"] = "Aspire.Hosting.CodeGeneration.TypeScript", + }; + + if (additionalConfiguration is not null) + { + foreach (var (key, value) in additionalConfiguration) { - ["AtsAssemblies:0"] = "Aspire.Hosting.CodeGeneration.Go", - ["AtsAssemblies:1"] = "Aspire.Hosting.CodeGeneration.TypeScript", - }) + configurationValues[key] = value; + } + } + + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(configurationValues) .Build(); var telemetry = new RemoteHostProfilingTelemetry(new ConfigurationBuilder().Build()); @@ -175,4 +232,41 @@ private static JsonRpcAuthenticationState CreateAuthenticationState(bool authent : new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["ASPIRE_REMOTE_APPHOST_TOKEN"] = "test-token" }) .Build()); + + private static void WriteProbeManifest(string manifestPath, IEnumerable? managedAssemblies = null, IEnumerable? nativeLibraries = null) + { + File.WriteAllText( + manifestPath, + JsonSerializer.Serialize( + new + { + ManagedAssemblies = managedAssemblies ?? [], + NativeLibraries = nativeLibraries ?? [] + }, + new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true + })); + } + + private sealed class TemporaryDirectory : IDisposable + { + private readonly DirectoryInfo _directory; + + public TemporaryDirectory() + { + _directory = Directory.CreateTempSubdirectory("aspire-remotehost-"); + } + + public string Path => _directory.FullName; + + public void Dispose() + { + if (Directory.Exists(Path)) + { + Directory.Delete(Path, recursive: true); + } + } + } } diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs index 4fbef60dd61..96fcdc457b3 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs @@ -188,11 +188,15 @@ public async Task ManifestCommand_WritesPackageProbeManifestWithoutCreatingLibsL Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Test.Package" && + assembly.GetProperty("packageId").GetString() == "Test.Package" && + assembly.GetProperty("packageVersion").GetString() == "1.0.0" && assembly.GetProperty("path").GetString() == Path.Combine(packageRoot, GetExpectedRuntimeAssemblyPath().Replace('/', Path.DirectorySeparatorChar))); Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Test.Package.resources" && assembly.GetProperty("culture").GetString() == "fr" && + assembly.GetProperty("packageId").GetString() == "Test.Package" && + assembly.GetProperty("packageVersion").GetString() == "1.0.0" && assembly.GetProperty("path").GetString() == Path.Combine(packageRoot, "lib", "net10.0", "fr", "Test.Package.resources.dll")); var nativeLibraries = manifest.RootElement.GetProperty("nativeLibraries").EnumerateArray().ToList(); @@ -261,6 +265,8 @@ public async Task RestoreAndManifestCommands_WritePackageCacheManifestWithoutCre Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Test.Package" && + assembly.GetProperty("packageId").GetString() == "Test.Package" && + assembly.GetProperty("packageVersion").GetString() == "1.0.0" && assembly.GetProperty("path").GetString() == expectedAssemblyPath); Assert.DoesNotContain( managedAssemblies, From e837c419fcd17351e8bc5aebc1d5316e1f9c25b1 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sat, 8 Aug 2026 14:46:10 -0400 Subject: [PATCH 33/73] Flow package probe manifest through repo apphost server Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../DotNetBasedAppHostServerProject.cs | 163 ++++++++++++++++++ ...BasedAppHostServerPackageReferenceTests.cs | 87 +++++++++- .../AssemblyLoaderTests.cs | 2 +- .../CodeGeneration/ApiReferenceExportTests.cs | 2 +- 4 files changed, 249 insertions(+), 5 deletions(-) diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index 1e6e9dfdca6..aef3c452008 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -31,6 +31,9 @@ internal sealed class DotNetBasedAppHostServerProject : IAppHostServerProject internal const string TargetFramework = "net10.0"; public const string BuildFolder = "build"; private const string AssemblyName = "AppHostServer"; + private const string PackageProbeSourcesFileName = "package-probe-sources.txt"; + private const string PackageProbeMetadataFileName = "package-probe-metadata.txt"; + private const string PackageProbeTargetsFileName = "package-probe-targets.txt"; private readonly string _projectModelPath; private readonly string _appPath; @@ -43,6 +46,7 @@ internal sealed class DotNetBasedAppHostServerProject : IAppHostServerProject private readonly IEnvironment _environment; private readonly ILogger _logger; private readonly string? _logFilePath; + private string? _integrationProbeManifestPath; // Boxed so "not read yet" and "read, and there is no answer" stay distinguishable without // re-parsing eng/Versions.props on every lookup. @@ -285,6 +289,26 @@ private XDocument CreateProjectFile(IEnumerable integratio // Disable Aspire SDK code generation doc.Root!.Add(new XElement("Target", new XAttribute("Name", "_CSharpWriteHostProjectMetadataSources"))); doc.Root!.Add(new XElement("Target", new XAttribute("Name", "_CSharpWriteProjectMetadataSources"))); + doc.Root!.Add( + new XElement("Target", + new XAttribute("Name", "_WriteAspirePackageProbeManifestInputs"), + new XAttribute("AfterTargets", "Build"), + new XAttribute("DependsOnTargets", "ResolveLockFileCopyLocalFiles"), + new XElement("WriteLinesToFile", + new XAttribute("File", Path.Combine(_projectModelPath, PackageProbeSourcesFileName)), + new XAttribute("Lines", "@(ReferenceCopyLocalPaths->'%(FullPath)')"), + new XAttribute("Overwrite", "true"), + new XAttribute("WriteOnlyWhenDifferent", "true")), + new XElement("WriteLinesToFile", + new XAttribute("File", Path.Combine(_projectModelPath, PackageProbeMetadataFileName)), + new XAttribute("Lines", "@(ReferenceCopyLocalPaths->'%(NuGetPackageId)|%(NuGetPackageVersion)|%(AssetType)')"), + new XAttribute("Overwrite", "true"), + new XAttribute("WriteOnlyWhenDifferent", "true")), + new XElement("WriteLinesToFile", + new XAttribute("File", Path.Combine(_projectModelPath, PackageProbeTargetsFileName)), + new XAttribute("Lines", "@(ReferenceCopyLocalPaths->'%(DestinationSubDirectory)%(Filename)%(Extension)')"), + new XAttribute("Overwrite", "true"), + new XAttribute("WriteOnlyWhenDifferent", "true")))); return doc; } @@ -490,6 +514,8 @@ public async Task PrepareAsync( NeedsCodeGeneration: false); } + await WriteIntegrationProbeManifestAsync(cancellationToken).ConfigureAwait(false); + return new AppHostServerPrepareResult( Success: true, Output: buildOutput, @@ -675,6 +701,19 @@ public async Task RunAsync( // for the dashboard to resolve static web assets correctly startInfo.Environment[KnownAspNetCoreConfigNames.Environment] = "Development"; + if (_integrationProbeManifestPath is not null) + { + _logger.LogDebug( + "Setting {EnvironmentVariable} to {Path}", + KnownConfigNames.IntegrationProbeManifestPath, + _integrationProbeManifestPath); + startInfo.Environment[KnownConfigNames.IntegrationProbeManifestPath] = _integrationProbeManifestPath; + } + else + { + startInfo.Environment.Remove(KnownConfigNames.IntegrationProbeManifestPath); + } + // Wire WithTerminal() for guest/polyglot AppHosts running from the repo. The // generated AppHostServer references Aspire.Hosting from the repo and DCP resolves // the terminal host via ASPIRE_TERMINAL_HOST_PATH or assembly metadata. No per-RID @@ -759,6 +798,130 @@ void OnStderr(string line) return new AppHostServerRunResult(_socketPath, outputCollector, execution); } + private async Task WriteIntegrationProbeManifestAsync(CancellationToken cancellationToken) + { + var sourcesPath = Path.Combine(_projectModelPath, PackageProbeSourcesFileName); + var metadataPath = Path.Combine(_projectModelPath, PackageProbeMetadataFileName); + var targetsPath = Path.Combine(_projectModelPath, PackageProbeTargetsFileName); + + if (!File.Exists(sourcesPath) || !File.Exists(metadataPath) || !File.Exists(targetsPath)) + { + _integrationProbeManifestPath = null; + return; + } + + var sourcePaths = await File.ReadAllLinesAsync(sourcesPath, cancellationToken).ConfigureAwait(false); + var metadataLines = await File.ReadAllLinesAsync(metadataPath, cancellationToken).ConfigureAwait(false); + var targetPaths = await File.ReadAllLinesAsync(targetsPath, cancellationToken).ConfigureAwait(false); + if (sourcePaths.Length != metadataLines.Length || sourcePaths.Length != targetPaths.Length) + { + throw new InvalidOperationException( + $"Package probe manifest inputs are inconsistent. Sources: {sourcePaths.Length}, metadata: {metadataLines.Length}, targets: {targetPaths.Length}."); + } + + var managedAssemblies = new List(); + var nativeLibraries = new List(); + + for (var i = 0; i < sourcePaths.Length; i++) + { + cancellationToken.ThrowIfCancellationRequested(); + + var metadata = ParsePackageProbeMetadata(metadataLines[i]); + if (string.IsNullOrWhiteSpace(metadata.PackageId) || + string.IsNullOrWhiteSpace(metadata.PackageVersion)) + { + continue; + } + + var sourcePath = sourcePaths[i]; + var targetPath = NormalizePackageProbeTargetPath(targetPaths[i], sourcePath); + if (string.Equals(metadata.AssetType, "native", StringComparison.OrdinalIgnoreCase)) + { + nativeLibraries.Add(new IntegrationPackageNativeLibrary + { + FileName = Path.GetFileName(targetPath), + Path = sourcePath + }); + continue; + } + + if (!sourcePath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + managedAssemblies.Add(new IntegrationPackageManagedAssembly + { + Name = Path.GetFileNameWithoutExtension(targetPath), + Culture = TryGetSatelliteCulture(targetPath, metadata.AssetType), + Path = sourcePath, + PackageId = metadata.PackageId, + PackageVersion = metadata.PackageVersion + }); + } + + if (managedAssemblies.Count == 0 && nativeLibraries.Count == 0) + { + _integrationProbeManifestPath = null; + return; + } + + _integrationProbeManifestPath = Path.Combine(_projectModelPath, IntegrationPackageProbeManifest.FileName); + await IntegrationPackageProbeManifest.WriteAsync( + _integrationProbeManifestPath, + IntegrationPackageProbeManifest.Create(managedAssemblies, nativeLibraries), + cancellationToken).ConfigureAwait(false); + } + + private static PackageProbeMetadata ParsePackageProbeMetadata(string line) + { + // Written from ReferenceCopyLocalPaths as: + // Contoso.Aspire.MetaPackage|1.2.3|runtime + // Empty fields are possible for project references; those entries are intentionally + // ignored because the probe manifest only preserves NuGet package ownership. + var parts = line.Split('|'); + if (parts.Length != 3) + { + throw new InvalidOperationException($"Package probe manifest metadata line has an unexpected format: '{line}'."); + } + + return new PackageProbeMetadata( + NormalizeOptionalValue(parts[0]), + NormalizeOptionalValue(parts[1]), + NormalizeOptionalValue(parts[2])); + } + + private static string NormalizePackageProbeTargetPath(string targetPath, string sourcePath) + { + if (string.IsNullOrWhiteSpace(targetPath)) + { + return Path.GetFileName(sourcePath); + } + + return targetPath.Replace('\\', '/').TrimStart('/'); + } + + private static string? TryGetSatelliteCulture(string relativePath, string? assetType) + { + if (!string.Equals(assetType, "resources", StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + var directoryName = Path.GetDirectoryName(relativePath.Replace('/', Path.DirectorySeparatorChar)); + if (string.IsNullOrWhiteSpace(directoryName)) + { + return null; + } + + return directoryName.Replace('\\', '/').Trim('/'); + } + + private static string? NormalizeOptionalValue(string value) + => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); + + private sealed record PackageProbeMetadata(string? PackageId, string? PackageVersion, string? AssetType); + private static string? FindNuGetConfig(string workingDirectory) { try diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs index 7f5ddf5f9c4..4f2064947f3 100644 --- a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs @@ -7,6 +7,7 @@ using Aspire.Cli.Tests.Mcp; using Aspire.Cli.Tests.TestServices; using Aspire.Cli.Tests.Utils; +using Aspire.Hosting; using Microsoft.Extensions.Logging.Abstractions; namespace Aspire.Cli.Tests.Projects; @@ -100,6 +101,82 @@ await project.CreateProjectFilesAsync( Assert.Equal(0, exitCode); } + [Fact] + public async Task PrepareWritesPackageProbeManifestForOutOfRepoIntegrations() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appPath = workspace.WorkspaceRoot.FullName; + var projectModelPath = Path.Combine(appPath, ".aspire_server"); + var packageDirectory = Path.Combine(appPath, "packages"); + Directory.CreateDirectory(packageDirectory); + + var primaryAssemblyPath = Path.Combine(packageDirectory, "Contoso.Hosting.dll"); + var secondaryAssemblyPath = Path.Combine(packageDirectory, "Contoso.Hosting.Extras.dll"); + var satelliteAssemblyPath = Path.Combine(packageDirectory, "fr", "Contoso.Hosting.resources.dll"); + Directory.CreateDirectory(Path.GetDirectoryName(satelliteAssemblyPath)!); + await File.WriteAllTextAsync(primaryAssemblyPath, string.Empty); + await File.WriteAllTextAsync(secondaryAssemblyPath, string.Empty); + await File.WriteAllTextAsync(satelliteAssemblyPath, string.Empty); + + var runner = new TestDotNetCliRunner + { + BuildAsyncCallback = (_, _, _, _) => + { + File.WriteAllLines( + Path.Combine(projectModelPath, "package-probe-sources.txt"), + [primaryAssemblyPath, secondaryAssemblyPath, satelliteAssemblyPath]); + File.WriteAllLines( + Path.Combine(projectModelPath, "package-probe-metadata.txt"), + [ + "Contoso.Aspire.MetaPackage|1.2.3|runtime", + "Contoso.Aspire.MetaPackage|1.2.3|runtime", + "Contoso.Aspire.MetaPackage|1.2.3|resources" + ]); + File.WriteAllLines( + Path.Combine(projectModelPath, "package-probe-targets.txt"), + [ + "Contoso.Hosting.dll", + "Contoso.Hosting.Extras.dll", + "fr/Contoso.Hosting.resources.dll" + ]); + + return 0; + } + }; + var processExecutionFactory = new TestProcessExecutionFactory(); + var project = CreateProject(appPath, projectModelPath, runner, processExecutionFactory); + + var result = await project.PrepareAsync( + "13.5.0", + [IntegrationReference.FromExactPackage("Contoso.Aspire.MetaPackage", "1.2.3")]); + + Assert.True(result.Success); + + var manifestPath = Path.Combine(projectModelPath, IntegrationPackageProbeManifest.FileName); + Assert.True(File.Exists(manifestPath)); + + var manifest = IntegrationPackageProbeManifest.Load(manifestPath); + Assert.True(manifest.TryGetRuntimeAssemblyNamesForPackage("contoso.aspire.metapackage", out var canonicalPackageId, out var assemblyNames)); + Assert.Equal("Contoso.Aspire.MetaPackage", canonicalPackageId); + Assert.Equal(["Contoso.Hosting", "Contoso.Hosting.Extras"], assemblyNames); + Assert.Contains( + manifest.ManagedAssemblies, + assembly => assembly.Name == "Contoso.Hosting.resources" && + assembly.Culture == "fr" && + assembly.PackageId == "Contoso.Aspire.MetaPackage" && + assembly.PackageVersion == "1.2.3"); + + var runResult = await project.RunAsync( + Environment.ProcessId, + environmentVariables: null, + additionalArgs: null, + debug: false, + runControl: null); + await using var execution = runResult.Execution; + + Assert.Equal(manifestPath, processExecutionFactory.LastEnvironmentVariables?[KnownConfigNames.IntegrationProbeManifestPath]); + } + /// /// aspire sdk export publishes documentation keyed on the requested version, so the /// restore has to fail when that version is unavailable rather than resolve to a later one. @@ -354,14 +431,18 @@ await CreateProject(appPath, exactModelPath) Assert.Contains("NU1102", exactOutput, StringComparison.Ordinal); } - private static DotNetBasedAppHostServerProject CreateProject(string appPath, string projectModelPath) + private static DotNetBasedAppHostServerProject CreateProject( + string appPath, + string projectModelPath, + TestDotNetCliRunner? runner = null, + TestProcessExecutionFactory? processExecutionFactory = null) => new( appPath, socketPath: "test.sock", repoRoot: appPath, - new TestDotNetCliRunner(), + runner ?? new TestDotNetCliRunner(), MockPackagingServiceFactory.Create(), - new TestProcessExecutionFactory(), + processExecutionFactory ?? new TestProcessExecutionFactory(), new TestEnvironment(), NullLogger.Instance, projectModelPath); diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs index 7dd692dc5bd..1905fd7e3d4 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs @@ -143,7 +143,7 @@ public void GetAssemblyNamesToLoad_AddsAssembliesOwnedByConfiguredPackageFromPro var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { - ["AtsAssemblies:0"] = "Contoso.Aspire.MetaPackage" + ["AtsAssemblies:0"] = "contoso.aspire.metapackage" }) .Build(); diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index 29c68f84955..cd0d4567656 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -116,7 +116,7 @@ public void ExportApi_UsesPackageProbeManifestAssembliesForRequestedPackage() ["ASPIRE_INTEGRATION_PROBE_MANIFEST_PATH"] = manifestPath }); - var export = service.ExportApi("TypeScript", "Contoso.Aspire.MetaPackage", "1.2.3"); + var export = service.ExportApi("TypeScript", "contoso.aspire.metapackage", "1.2.3"); Assert.Equal("Contoso.Aspire.MetaPackage", export.GetProperty("package").GetProperty("name").GetString()); From 59bedbfc38402fc22fca28fd521a63bd86791ec1 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sat, 8 Aug 2026 15:14:34 -0400 Subject: [PATCH 34/73] Make TypeScript options qualifiers injective Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../TypeScriptApiProjector.cs | 80 +-- .../AtsTypeScriptCodeGeneratorTests.cs | 57 ++- .../Snapshots/AtsGeneratedAspire.verified.ts | 204 ++++---- ...eneratorTests.ApiDeclarations.verified.txt | 256 +++++----- ...CodeGeneratorTests.ApiExport.verified.json | 416 ++++++++-------- ...TwoPassScanningGeneratedAspire.verified.ts | 466 +++++++++--------- .../WithDataVolumeOptionsMerged.verified.ts | 2 +- 7 files changed, 741 insertions(+), 740 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index bd6e364bc4b..22443e8164c 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -68,20 +68,12 @@ export interface InteractionInputCollectionPromise extends PromiseLikeThe client parameter every entry-point function takes first. private const string EntryPointClientParameterName = "client"; /// The declared type of . private const string EntryPointClientParameterType = "AspireClientRpc"; - private static readonly string[] s_optionsInterfaceQualifierPrefixes = - [ - $"{AtsConstants.AspireHostingAssembly}.", - "Aspire." - ]; - public TypeScriptApiProjector(AtsContext context) { ArgumentNullException.ThrowIfNull(context); @@ -1679,11 +1671,11 @@ internal static string ToPascalCase(string name) /// /// The core hosting package keeps unqualified names. It is present in every scan, so its names /// were never the ones at risk, and leaving them alone confines the rename to the packages that - /// actually needed it. The qualifier drops a leading Aspire.Hosting. (or Aspire.) - /// and encodes the remaining separators, so Aspire.Hosting.Azure.EventHubs yields - /// Azure_EventHubsRunAsEmulatorOptions and Aspire.Hosting.Redis yields - /// RedisWithDataVolumeOptions. See for why the - /// encoding has to be reversible rather than simply stripping the punctuation. + /// actually needed it. Other packages carry an encoding of their full assembly name, so + /// Aspire.Hosting.Azure.EventHubs yields + /// Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions. See + /// for why the encoding has to be reversible rather + /// than simply stripping the punctuation or common prefixes. /// /// internal static string GetOptionsInterfaceName(string methodName, string owningAssemblyName) @@ -1710,11 +1702,11 @@ internal static string GetOptionsInterfaceName(string methodName, string owningA /// Contoso.Foo.Bar and Contoso.FooBar would both yield ContosoFooBar. /// /// - /// So separators are encoded rather than removed. '.' becomes '_', a literal - /// '_' is doubled, and any other character becomes _x followed by its hex code - /// point. Every rule is reversible, so distinct assembly names cannot share a qualifier. - /// Assembly and package identity is case-insensitive, so casing alone never distinguishes two - /// assemblies and normalizing the first character is safe. + /// So every non-alphanumeric UTF-16 code unit is encoded rather than removed, and the full + /// assembly name is kept. Each escape is _xNNNN_ with a terminator, so + /// Contoso.Foo-Bar cannot alias Contoso.Foo.x2DBar, and U+0123 followed + /// by 4 cannot alias U+1234. A leading digit is escaped too because TypeScript + /// identifiers may not start with one. /// /// private static string GetOptionsInterfaceQualifier(string owningAssemblyName) @@ -1725,39 +1717,17 @@ private static string GetOptionsInterfaceQualifier(string owningAssemblyName) return string.Empty; } - var remainder = owningAssemblyName; - foreach (var prefix in s_optionsInterfaceQualifierPrefixes) + var qualifier = new StringBuilder(owningAssemblyName.Length); + for (var i = 0; i < owningAssemblyName.Length; i++) { - if (remainder.StartsWith(prefix, StringComparison.Ordinal)) + var character = owningAssemblyName[i]; + if (char.IsAsciiLetter(character) || (i > 0 && char.IsAsciiDigit(character))) { - remainder = remainder[prefix.Length..]; - break; + qualifier.Append(character); + continue; } - } - - var qualifier = new StringBuilder(remainder.Length); - foreach (var character in remainder) - { - switch (character) - { - case '.': - qualifier.Append('_'); - break; - case '_': - qualifier.Append("__"); - break; - default: - if (char.IsAsciiLetterOrDigit(character)) - { - qualifier.Append(character); - } - else - { - qualifier.Append("_x").Append(((int)character).ToString("X2", CultureInfo.InvariantCulture)); - } - break; - } + AppendEscapedCodeUnit(qualifier, character); } if (qualifier.Length == 0) @@ -1765,17 +1735,15 @@ private static string GetOptionsInterfaceQualifier(string owningAssemblyName) return string.Empty; } - // A TypeScript identifier cannot start with a digit, and an assembly name legitimately can - // (for example "3rdParty.Aspire"). Prefixing keeps the result parseable, and cannot alias a - // name that already begins with '_' because that character encodes to a doubled '_'. - if (char.IsAsciiDigit(qualifier[0])) - { - qualifier.Insert(0, '_'); + return qualifier.ToString(); - return qualifier.ToString(); + static void AppendEscapedCodeUnit(StringBuilder builder, char codeUnit) + { + builder + .Append("_x") + .Append(((int)codeUnit).ToString("X4", CultureInfo.InvariantCulture)) + .Append('_'); } - - return ToPascalCase(qualifier.ToString()); } /// diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index c323d6b940f..22ad472de65 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1925,7 +1925,7 @@ public void Scanner_PackageManagerMethods_ExpandToAllJavaScriptResourceTypes(str /// alongside every other package. Only Aspire.Hosting keeps unqualified names, so the /// fixture's own interfaces carry this prefix. /// - private const string TestOptionsPrefix = "CodeGeneration_TypeScript_Tests"; + private const string TestOptionsPrefix = "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests"; [Fact] public async Task ApiExportUsesTheSameResolvedSignaturesAsGeneratedSource() @@ -2547,8 +2547,8 @@ static string EmulatorInterfaceName(TypeScriptApiProjector projector, string pac => projector.ResolveOptionsInterfaceName( projector.Resolved.Context.Capabilities.Single(c => c.CapabilityId == $"{packageName}/runAsEmulator")); - Assert.Equal("Azure_EventHubsRunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); - Assert.Equal("Azure_ServiceBusRunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); + Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); + Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); Assert.Equal( EmulatorInterfaceName(hubsAlone, CollisionPackageA), @@ -2616,8 +2616,24 @@ public void OptionsInterfaceQualifiersDistinguishAssembliesThatDifferOnlyBySepar var joined = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.FooBar"); Assert.NotEqual(dotted, joined); - Assert.Equal("Contoso_Foo_BarRunAsEmulatorOptions", dotted); - Assert.Equal("Contoso_FooBarRunAsEmulatorOptions", joined); + Assert.Equal("Contoso_x002E_Foo_x002E_BarRunAsEmulatorOptions", dotted); + Assert.Equal("Contoso_x002E_FooBarRunAsEmulatorOptions", joined); + } + + /// + /// Escape sequences are terminated so characters after the escaped code unit cannot become part + /// of the escape itself. + /// + [Fact] + public void OptionsInterfaceQualifiersUseTerminatedEscapes() + { + Assert.NotEqual( + TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.Foo-Bar"), + TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.Foo.x2DBar")); + + Assert.NotEqual( + TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.\u01234"), + TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.\u1234")); } /// @@ -2635,11 +2651,28 @@ public void OptionsInterfaceQualifiersEscapeAssemblyNamesThatStartWithADigit() { var name = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "3rdParty.Aspire"); - Assert.Equal("_3rdParty_AspireRunAsEmulatorOptions", name); + Assert.Equal("_x0033_rdParty_x002E_AspireRunAsEmulatorOptions", name); Assert.True(name[0] is '_' or '$' || char.IsLetter(name[0]), $"'{name}' is not a valid TypeScript identifier."); Assert.NotEqual(name, TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "_3rdParty.Aspire")); } + /// + /// Non-core assemblies are qualified by their complete names, not by a shortened suffix that can + /// overlap other assemblies. + /// + [Fact] + public void OptionsInterfaceQualifiersUseTheFullAssemblyName() + { + var hostingRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Aspire.Hosting.Redis"); + var aspireRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Aspire.Redis"); + var bareRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Redis"); + + Assert.Equal("Aspire_x002E_Hosting_x002E_RedisRunAsEmulatorOptions", hostingRedis); + Assert.Equal("Aspire_x002E_RedisRunAsEmulatorOptions", aspireRedis); + Assert.Equal("RedisRunAsEmulatorOptions", bareRedis); + Assert.Equal(3, new[] { hostingRedis, aspireRedis, bareRedis }.Distinct(StringComparer.Ordinal).Count()); + } + /// /// An options interface is documented by, and keyed to, the assembly whose capability produced /// it rather than the package the export was requested for. @@ -2668,15 +2701,15 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() documentedOptions, item => { - Assert.Equal("Azure_EventHubsRunAsEmulatorOptions", item.Name); + Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions", item.Name); Assert.Equal(CollisionPackageA, item.OwningAssemblyName); }); var serviceBusDeclaration = Assert.Single( model.Declarations, - declaration => declaration.Content.Contains("Azure_ServiceBusRunAsEmulatorOptions", StringComparison.Ordinal)); + declaration => declaration.Content.Contains("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions", StringComparison.Ordinal)); - Assert.Equal($"{CollisionPackageB}:options:Azure_ServiceBusRunAsEmulatorOptions", serviceBusDeclaration.Id); + Assert.Equal($"{CollisionPackageB}:options:Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions", serviceBusDeclaration.Id); Assert.Equal(CollisionPackageB, serviceBusDeclaration.OwningAssemblyName); } @@ -2694,7 +2727,7 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() /// Both directions fail under the old scheme, but at different assertions, and that asymmetry /// is why the body comparison is here. Event Hubs was scanned first and kept the unsuffixed /// base name, so it fails only on the name: it produced RunAsEmulatorOptions rather than - /// Azure_EventHubsRunAsEmulatorOptions. Service Bus lost that draw during full generation + /// the Event Hubs assembly-qualified name. Service Bus lost that draw during full generation /// and was suffixed there while its own single-package export was not, so it disagreed about /// the interface itself. Checking only that the exported name appears among the generated names /// would have missed it, because the name did appear -- it just belonged to Event Hubs. The old @@ -2705,8 +2738,8 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() /// /// [Theory] - [InlineData(CollisionPackageA, "Azure_EventHubsRunAsEmulatorOptions")] - [InlineData(CollisionPackageB, "Azure_ServiceBusRunAsEmulatorOptions")] + [InlineData(CollisionPackageA, "Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions")] + [InlineData(CollisionPackageB, "Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions")] public void ApiExportNamesACollidingOptionsInterfaceTheWayGenerationDoes(string packageName, string expectedInterfaceName) { var fullContext = CreateEmulatorCollisionContext(); diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts index bce90e5304f..5dde77ebe44 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts @@ -172,47 +172,47 @@ export namespace TestConfigs { // Options Interfaces // ============================================================================ -export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions { databaseName?: string; } -export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions { port?: number; } -export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { mode?: TestPersistenceMode; } @@ -667,7 +667,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -679,7 +679,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addTestRedis(name, options)), this._client); } @@ -769,7 +769,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -784,7 +784,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -807,7 +807,7 @@ export interface TestDatabaseResource { * Adds a data volume * @param options Additional options. */ - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestDatabaseResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestDatabaseResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestDatabaseResourcePromise; /** Adds a categorized label to the resource */ @@ -820,12 +820,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -837,7 +837,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withOptionalString(options)), this._client); } @@ -1380,7 +1380,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -1420,7 +1420,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestDatabaseResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -1440,11 +1440,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -1471,17 +1471,17 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1502,7 +1502,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1529,21 +1529,21 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1556,12 +1556,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1576,17 +1576,17 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1607,7 +1607,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1634,21 +1634,21 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1661,12 +1661,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1700,7 +1700,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -1720,7 +1720,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -1741,7 +1741,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -1880,7 +1880,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2056,7 +2056,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { + async getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2089,7 +2089,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2137,7 +2137,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -2219,7 +2219,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2241,7 +2241,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -2296,15 +2296,15 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return this._promise.then(onfulfilled, onrejected); } - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -2340,7 +2340,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -2388,7 +2388,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -2396,7 +2396,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -2404,7 +2404,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -2424,11 +2424,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -2452,7 +2452,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2467,7 +2467,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2500,12 +2500,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2517,7 +2517,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2532,7 +2532,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2565,12 +2565,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2602,7 +2602,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -2708,7 +2708,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2951,7 +2951,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2973,7 +2973,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3028,7 +3028,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3052,7 +3052,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3112,11 +3112,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -3140,7 +3140,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3153,7 +3153,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3182,12 +3182,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3199,7 +3199,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3212,7 +3212,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3241,12 +3241,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3278,7 +3278,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -3364,7 +3364,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -3577,7 +3577,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -3599,7 +3599,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3654,7 +3654,7 @@ class ResourcePromiseImpl implements ResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3674,7 +3674,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3726,11 +3726,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index 074aa266e99..3cc0ed87d56 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -1,12 +1,12 @@ // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource export interface CSharpAppResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -20,21 +20,21 @@ export interface CSharpAppResource { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise export interface CSharpAppResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -48,20 +48,20 @@ export interface CSharpAppResourcePromise { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource export interface ContainerRegistryResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -74,20 +74,20 @@ export interface ContainerRegistryResource { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise export interface ContainerRegistryResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -100,21 +100,21 @@ export interface ContainerRegistryResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource export interface ContainerResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -128,21 +128,21 @@ export interface ContainerResource { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise export interface ContainerResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -156,33 +156,33 @@ export interface ContainerResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder export interface DistributedApplicationBuilder { - addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise export interface DistributedApplicationBuilderPromise { - addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource export interface DotnetToolResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -196,21 +196,21 @@ export interface DotnetToolResource { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise export interface DotnetToolResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -224,21 +224,21 @@ export interface DotnetToolResourcePromise { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource export interface ExecutableResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -252,21 +252,21 @@ export interface ExecutableResource { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise export interface ExecutableResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -280,20 +280,20 @@ export interface ExecutableResourcePromise { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource export interface ExternalServiceResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -306,20 +306,20 @@ export interface ExternalServiceResource { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise export interface ExternalServiceResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -332,20 +332,20 @@ export interface ExternalServiceResourcePromise { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource export interface ParameterResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -358,20 +358,20 @@ export interface ParameterResource { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise export interface ParameterResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -384,21 +384,21 @@ export interface ParameterResourcePromise { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource export interface ProjectResource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -412,21 +412,21 @@ export interface ProjectResource { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise export interface ProjectResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -440,20 +440,20 @@ export interface ProjectResourcePromise { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource export interface Resource { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -466,20 +466,20 @@ export interface Resource { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise export interface ResourcePromise { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -492,8 +492,8 @@ export interface ResourcePromise { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } @@ -586,13 +586,13 @@ export interface TestCollectionContextPromise extends PromiseLike Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -606,21 +606,21 @@ export interface TestDatabaseResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise export interface TestDatabaseResourcePromise extends PromiseLike { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; withConfig(config: TestConfigDto): TestDatabaseResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -634,8 +634,8 @@ export interface TestDatabaseResourcePromise extends PromiseLike>; getMetadata(): Promise>; @@ -669,7 +669,7 @@ export interface TestRedisResource extends ResourceBuilderBase { withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -681,26 +681,26 @@ export interface TestRedisResource extends ResourceBuilderBase { withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise export interface TestRedisResourcePromise extends PromiseLike { - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; withConfig(config: TestConfigDto): TestRedisResourcePromise; getTags(): Promise>; getMetadata(): Promise>; @@ -709,7 +709,7 @@ export interface TestRedisResourcePromise extends PromiseLike withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -721,17 +721,17 @@ export interface TestRedisResourcePromise extends PromiseLike withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } @@ -758,13 +758,13 @@ export interface TestResourceContextPromise extends PromiseLike Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -779,21 +779,21 @@ export interface TestVaultResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise export interface TestVaultResourcePromise extends PromiseLike { - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; withConfig(config: TestConfigDto): TestVaultResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -808,63 +808,63 @@ export interface TestVaultResourcePromise extends PromiseLike withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions -export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions { databaseName?: string; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestRedisOptions -export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions { port?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions -export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions -export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithDataVolumeOptions -export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions -export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions -export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions -export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalStringOptions -export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithPersistenceOptions -export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { mode?: TestPersistenceMode; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index ffd306cc5ff..0d976c57dda 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -24,14 +24,14 @@ "id": "method:CSharpAppResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "CSharpAppResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -120,14 +120,14 @@ "id": "method:CSharpAppResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "CSharpAppResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -364,7 +364,7 @@ "id": "method:CSharpAppResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging", @@ -376,7 +376,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -385,7 +385,7 @@ "id": "method:CSharpAppResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging with file path", @@ -402,7 +402,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -491,14 +491,14 @@ "id": "method:ContainerRegistryResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerRegistryResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -571,14 +571,14 @@ "id": "method:ContainerRegistryResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -799,7 +799,7 @@ "id": "method:ContainerRegistryResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging", @@ -811,7 +811,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -820,7 +820,7 @@ "id": "method:ContainerRegistryResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging with file path", @@ -837,7 +837,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -927,14 +927,14 @@ "id": "method:ContainerResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -1023,14 +1023,14 @@ "id": "method:ContainerResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -1267,7 +1267,7 @@ "id": "method:ContainerResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging", @@ -1279,7 +1279,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -1288,7 +1288,7 @@ "id": "method:ContainerResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging with file path", @@ -1305,7 +1305,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -1392,7 +1392,7 @@ "id": "method:DistributedApplicationBuilder.addTestRedis", "kind": "method", "name": "addTestRedis", - "declaration": "addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise", + "declaration": "addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestRedis", "returnType": "TestRedisResourcePromise", "summary": "Adds a test Redis resource from ATS documentation.", @@ -1405,7 +1405,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsAddTestRedisOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", "optional": true } ] @@ -1443,14 +1443,14 @@ "id": "method:DotnetToolResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "DotnetToolResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -1539,14 +1539,14 @@ "id": "method:DotnetToolResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "DotnetToolResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -1783,7 +1783,7 @@ "id": "method:DotnetToolResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging", @@ -1795,7 +1795,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -1804,7 +1804,7 @@ "id": "method:DotnetToolResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging with file path", @@ -1821,7 +1821,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -1912,14 +1912,14 @@ "id": "method:ExecutableResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExecutableResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -2008,14 +2008,14 @@ "id": "method:ExecutableResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExecutableResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -2252,7 +2252,7 @@ "id": "method:ExecutableResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging", @@ -2264,7 +2264,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -2273,7 +2273,7 @@ "id": "method:ExecutableResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging with file path", @@ -2290,7 +2290,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -2379,14 +2379,14 @@ "id": "method:ExternalServiceResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExternalServiceResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -2459,14 +2459,14 @@ "id": "method:ExternalServiceResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExternalServiceResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -2687,7 +2687,7 @@ "id": "method:ExternalServiceResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging", @@ -2699,7 +2699,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -2708,7 +2708,7 @@ "id": "method:ExternalServiceResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging with file path", @@ -2725,7 +2725,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -2815,14 +2815,14 @@ "id": "method:ParameterResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ParameterResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -2895,14 +2895,14 @@ "id": "method:ParameterResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ParameterResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -3123,7 +3123,7 @@ "id": "method:ParameterResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging", @@ -3135,7 +3135,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -3144,7 +3144,7 @@ "id": "method:ParameterResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging with file path", @@ -3161,7 +3161,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -3251,14 +3251,14 @@ "id": "method:ProjectResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ProjectResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -3347,14 +3347,14 @@ "id": "method:ProjectResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ProjectResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -3591,7 +3591,7 @@ "id": "method:ProjectResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging", @@ -3603,7 +3603,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -3612,7 +3612,7 @@ "id": "method:ProjectResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging with file path", @@ -3629,7 +3629,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -3719,14 +3719,14 @@ "id": "method:Resource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -3799,14 +3799,14 @@ "id": "method:Resource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -4027,7 +4027,7 @@ "id": "method:Resource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ResourcePromise", "summary": "Configures resource logging", @@ -4039,7 +4039,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -4048,7 +4048,7 @@ "id": "method:Resource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ResourcePromise", "summary": "Configures resource logging with file path", @@ -4065,7 +4065,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -4473,14 +4473,14 @@ "id": "method:TestDatabaseResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestDatabaseResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -4569,14 +4569,14 @@ "id": "method:TestDatabaseResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestDatabaseResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -4813,7 +4813,7 @@ "id": "method:TestDatabaseResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging", @@ -4825,7 +4825,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -4834,7 +4834,7 @@ "id": "method:TestDatabaseResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging with file path", @@ -4851,7 +4851,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -4996,7 +4996,7 @@ "id": "method:TestRedisResource.addTestChildDatabase", "kind": "method", "name": "addTestChildDatabase", - "declaration": "addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise", + "declaration": "addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestChildDatabase", "returnType": "TestDatabaseResourcePromise", "summary": "Adds a child database to a test Redis resource", @@ -5009,7 +5009,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", "optional": true } ] @@ -5018,14 +5018,14 @@ "id": "method:TestRedisResource.withPersistence", "kind": "method", "name": "withPersistence", - "declaration": "withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise", + "declaration": "withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withPersistence", "returnType": "TestRedisResourcePromise", "summary": "Configures the Redis resource with persistence", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithPersistenceOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "optional": true } ] @@ -5034,14 +5034,14 @@ "id": "method:TestRedisResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestRedisResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -5164,14 +5164,14 @@ "id": "method:TestRedisResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestRedisResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -5349,14 +5349,14 @@ "id": "method:TestRedisResource.getStatusAsync", "kind": "method", "name": "getStatusAsync", - "declaration": "getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E", + "declaration": "getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getStatusAsync", "returnType": "Promise\u003Cstring\u003E", "summary": "Gets the status of the resource asynchronously", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", "optional": true } ] @@ -5381,7 +5381,7 @@ "id": "method:TestRedisResource.waitForReadyAsync", "kind": "method", "name": "waitForReadyAsync", - "declaration": "waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", + "declaration": "waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync", "returnType": "Promise\u003Cboolean\u003E", "summary": "Waits for the resource to be ready", @@ -5393,7 +5393,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", "optional": true } ] @@ -5418,14 +5418,14 @@ "id": "method:TestRedisResource.withDataVolume", "kind": "method", "name": "withDataVolume", - "declaration": "withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise", + "declaration": "withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDataVolume", "returnType": "TestRedisResourcePromise", "summary": "Adds a data volume with persistence", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithDataVolumeOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "optional": true } ] @@ -5518,7 +5518,7 @@ "id": "method:TestRedisResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging", @@ -5530,7 +5530,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -5539,7 +5539,7 @@ "id": "method:TestRedisResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging with file path", @@ -5556,7 +5556,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -5704,14 +5704,14 @@ "id": "method:TestVaultResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise", + "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestVaultResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "optional": true } ] @@ -5800,14 +5800,14 @@ "id": "method:TestVaultResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise", + "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestVaultResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "optional": true } ] @@ -6060,7 +6060,7 @@ "id": "method:TestVaultResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging", @@ -6072,7 +6072,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "optional": true } ] @@ -6081,7 +6081,7 @@ "id": "method:TestVaultResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging with file path", @@ -6098,7 +6098,7 @@ }, { "name": "options", - "type": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "optional": true } ] @@ -6173,15 +6173,15 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions.databaseName", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions.databaseName", "kind": "property", "name": "databaseName", "declaration": "databaseName?: string" @@ -6189,15 +6189,15 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsAddTestRedisOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsAddTestRedisOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsAddTestRedisOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsAddTestRedisOptions.port", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions.port", "kind": "property", "name": "port", "declaration": "port?: number" @@ -6205,15 +6205,15 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions.cancellationToken", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions.cancellationToken", "kind": "property", "name": "cancellationToken", "declaration": "cancellationToken?: AbortSignal | CancellationToken" @@ -6221,15 +6221,15 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions.cancellationToken", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions.cancellationToken", "kind": "property", "name": "cancellationToken", "declaration": "cancellationToken?: AbortSignal | CancellationToken" @@ -6237,21 +6237,21 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsWithDataVolumeOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsWithDataVolumeOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithDataVolumeOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsWithDataVolumeOptions.name", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.name", "kind": "property", "name": "name", "declaration": "name?: string" }, { - "id": "property:CodeGeneration_TypeScript_TestsWithDataVolumeOptions.isReadOnly", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.isReadOnly", "kind": "property", "name": "isReadOnly", "declaration": "isReadOnly?: boolean" @@ -6259,21 +6259,21 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions.enableConsole", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions.maxFiles", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6281,21 +6281,21 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions.enableConsole", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions.maxFiles", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6303,15 +6303,15 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions.callback", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions.callback", "kind": "property", "name": "callback", "declaration": "callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E" @@ -6319,21 +6319,21 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsWithOptionalStringOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsWithOptionalStringOptions.value", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions.value", "kind": "property", "name": "value", "declaration": "value?: string" }, { - "id": "property:CodeGeneration_TypeScript_TestsWithOptionalStringOptions.enabled", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions.enabled", "kind": "property", "name": "enabled", "declaration": "enabled?: boolean" @@ -6341,15 +6341,15 @@ ] }, { - "id": "options:CodeGeneration_TypeScript_TestsWithPersistenceOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "kind": "options", - "name": "CodeGeneration_TypeScript_TestsWithPersistenceOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/CodeGeneration_TypeScript_TestsWithPersistenceOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "members": [ { - "id": "property:CodeGeneration_TypeScript_TestsWithPersistenceOptions.mode", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions.mode", "kind": "property", "name": "mode", "declaration": "mode?: TestPersistenceMode" @@ -6363,102 +6363,102 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Resource {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface Resource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourcePromise {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface ResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString", @@ -6528,12 +6528,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext", @@ -6548,12 +6548,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", @@ -6568,62 +6568,62 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions {\n databaseName?: string;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions {\n databaseName?: string;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsAddTestRedisOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions {\n port?: number;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions {\n port?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsGetStatusAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithDataVolumeOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithOptionalStringOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:CodeGeneration_TypeScript_TestsWithPersistenceOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" }, { "id": "Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle", diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts index 6c4219b9c08..26d6f818caf 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts @@ -1530,57 +1530,57 @@ export interface ArgOptions { defaultValue?: string; } -export interface BuildOptions { - /** The logger used while resolving values. */ - resourceLogger?: Awaitable; - /** A cancellation token. */ - cancellationToken?: AbortSignal | CancellationToken; -} - -export interface CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions { databaseName?: string; } -export interface CodeGeneration_TypeScript_TestsAddTestRedisOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions { port?: number; } -export interface CodeGeneration_TypeScript_TestsGetStatusAsyncOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface CodeGeneration_TypeScript_TestsWithMergeLoggingOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -export interface CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -export interface CodeGeneration_TypeScript_TestsWithOptionalStringOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions { value?: string; enabled?: boolean; } -export interface CodeGeneration_TypeScript_TestsWithPersistenceOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { mode?: TestPersistenceMode; } +export interface BuildOptions { + /** The logger used while resolving values. */ + resourceLogger?: Awaitable; + /** A cancellation token. */ + cancellationToken?: AbortSignal | CancellationToken; +} + export interface CompleteStepMarkdownOptions { completionState?: string; cancellationToken?: AbortSignal | CancellationToken; @@ -10946,7 +10946,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -11167,7 +11167,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addHealthCheck(name, check)), this._client); } - addTestRedis(name: string, options?: CodeGeneration_TypeScript_TestsAddTestRedisOptions): TestRedisResourcePromise { + addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.addTestRedis(name, options)), this._client); } @@ -14688,7 +14688,7 @@ export interface ContainerRegistryResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; /** Sets the created timestamp */ @@ -14701,7 +14701,7 @@ export interface ContainerRegistryResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; /** Configures with nested DTO */ @@ -14730,12 +14730,12 @@ export interface ContainerRegistryResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; /** Configures a route with middleware */ @@ -15005,7 +15005,7 @@ export interface ContainerRegistryResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -16508,7 +16508,7 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -16560,11 +16560,11 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -17335,7 +17335,7 @@ export interface ContainerResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -17350,7 +17350,7 @@ export interface ContainerResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -17381,12 +17381,12 @@ export interface ContainerResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -18144,7 +18144,7 @@ export interface ContainerResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -18159,7 +18159,7 @@ export interface ContainerResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -18190,12 +18190,12 @@ export interface ContainerResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -20543,7 +20543,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ContainerResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -20649,7 +20649,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise { const callback = options?.callback; return new ContainerResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -20877,7 +20877,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -20899,7 +20899,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -21318,7 +21318,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -21342,7 +21342,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -21398,11 +21398,11 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -21987,7 +21987,7 @@ export interface CSharpAppResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22002,7 +22002,7 @@ export interface CSharpAppResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22033,12 +22033,12 @@ export interface CSharpAppResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -22611,7 +22611,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22626,7 +22626,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22657,12 +22657,12 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -24569,7 +24569,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise { const value = options?.value; const enabled = options?.enabled; return new CSharpAppResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -24675,7 +24675,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { const callback = options?.callback; return new CSharpAppResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -24903,7 +24903,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -24925,7 +24925,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -25276,7 +25276,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -25300,7 +25300,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -25356,11 +25356,11 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -25967,7 +25967,7 @@ export interface DotnetToolResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): DotnetToolResourcePromise; /** Configures environment with callback (test version) */ @@ -25982,7 +25982,7 @@ export interface DotnetToolResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): DotnetToolResourcePromise; /** Configures with nested DTO */ @@ -26013,12 +26013,12 @@ export interface DotnetToolResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; /** Configures a route with middleware */ @@ -26613,7 +26613,7 @@ export interface DotnetToolResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): DotnetToolResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -29389,7 +29389,7 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -29445,11 +29445,11 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): DotnetToolResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -30030,7 +30030,7 @@ export interface ExecutableResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExecutableResourcePromise; /** Configures environment with callback (test version) */ @@ -30045,7 +30045,7 @@ export interface ExecutableResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExecutableResourcePromise; /** Configures with nested DTO */ @@ -30076,12 +30076,12 @@ export interface ExecutableResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; /** Configures a route with middleware */ @@ -30643,7 +30643,7 @@ export interface ExecutableResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExecutableResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -33291,7 +33291,7 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExecutableResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -33347,11 +33347,11 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExecutableResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -33638,7 +33638,7 @@ export interface ExternalServiceResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExternalServiceResourcePromise; /** Sets the created timestamp */ @@ -33651,7 +33651,7 @@ export interface ExternalServiceResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; /** Configures with nested DTO */ @@ -33680,12 +33680,12 @@ export interface ExternalServiceResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; /** Configures a route with middleware */ @@ -33960,7 +33960,7 @@ export interface ExternalServiceResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ExternalServiceResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -35491,7 +35491,7 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -35543,11 +35543,11 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -35843,7 +35843,7 @@ export interface ParameterResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -35856,7 +35856,7 @@ export interface ParameterResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -35885,12 +35885,12 @@ export interface ParameterResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -36173,7 +36173,7 @@ export interface ParameterResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -36186,7 +36186,7 @@ export interface ParameterResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -36215,12 +36215,12 @@ export interface ParameterResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -37182,7 +37182,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ParameterResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -37268,7 +37268,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise { const callback = options?.callback; return new ParameterResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -37481,7 +37481,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -37503,7 +37503,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -37706,7 +37706,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -37726,7 +37726,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -37778,11 +37778,11 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -38368,7 +38368,7 @@ export interface ProjectResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -38383,7 +38383,7 @@ export interface ProjectResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -38414,12 +38414,12 @@ export interface ProjectResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -38992,7 +38992,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -39007,7 +39007,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -39038,12 +39038,12 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -40951,7 +40951,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ProjectResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -41057,7 +41057,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise { const callback = options?.callback; return new ProjectResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -41285,7 +41285,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -41307,7 +41307,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -41658,7 +41658,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -41682,7 +41682,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -41738,11 +41738,11 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -42512,7 +42512,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -42527,7 +42527,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -42558,12 +42558,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -43321,7 +43321,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestDatabaseResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -46518,7 +46518,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -46574,11 +46574,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -47373,17 +47373,17 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -47404,7 +47404,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -47431,21 +47431,21 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -47458,12 +47458,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -48246,17 +48246,17 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -48277,7 +48277,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -48304,21 +48304,21 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -48331,12 +48331,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -50745,7 +50745,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -50765,7 +50765,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -50786,7 +50786,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -50925,7 +50925,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -51101,7 +51101,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { + async getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51134,7 +51134,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51182,7 +51182,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -51264,7 +51264,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -51286,7 +51286,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -51717,15 +51717,15 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - addTestChildDatabase(name: string, options?: CodeGeneration_TypeScript_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: CodeGeneration_TypeScript_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -51761,7 +51761,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -51809,7 +51809,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: CodeGeneration_TypeScript_TestsGetStatusAsyncOptions): Promise { + getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -51817,7 +51817,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: CodeGeneration_TypeScript_TestsWaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -51825,7 +51825,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: CodeGeneration_TypeScript_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -51845,11 +51845,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -52619,7 +52619,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -52634,7 +52634,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -52667,12 +52667,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -53430,7 +53430,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -53445,7 +53445,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -53478,12 +53478,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -55830,7 +55830,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -55936,7 +55936,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -56179,7 +56179,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -56201,7 +56201,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -56620,7 +56620,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -56644,7 +56644,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -56704,11 +56704,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -57310,7 +57310,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57323,7 +57323,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57352,12 +57352,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -57627,7 +57627,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57640,7 +57640,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57669,12 +57669,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -58595,7 +58595,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -58681,7 +58681,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -58894,7 +58894,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -58916,7 +58916,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -59111,7 +59111,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: CodeGeneration_TypeScript_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -59131,7 +59131,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: CodeGeneration_TypeScript_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -59183,11 +59183,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: CodeGeneration_TypeScript_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts index 7209354cb02..f326f9e80a2 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts @@ -1,4 +1,4 @@ -export interface CodeGeneration_TypeScript_TestsWithDataVolumeOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } \ No newline at end of file From 8693974860407a13ed4f8ce0e485da9555f42daa Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 00:33:46 -0400 Subject: [PATCH 35/73] Guard TypeScript options interface collisions Implement selective package qualification for generated TypeScript options interfaces and add a TypeScript API compatibility guard for future unqualified name collisions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...e.Hosting.CodeGeneration.TypeScript.csproj | 1 + .../TypeScriptApiProjector.cs | 37 +- .../TypeScriptOptionsInterfaceNaming.cs | 56 ++ .../AtsTypeScriptCodeGeneratorTests.cs | 20 +- .../Snapshots/AtsGeneratedAspire.verified.ts | 192 +++---- ...eneratorTests.ApiDeclarations.verified.txt | 260 +++++----- ...CodeGeneratorTests.ApiExport.verified.json | 448 ++++++++-------- ...TwoPassScanningGeneratedAspire.verified.ts | 486 +++++++++--------- .../TypeScriptApiCompatTests.cs | 54 ++ .../TypeScriptApiCompat.csproj | 4 + .../TypeScriptApiCompatRunner.cs | 1 + .../TypeScriptOptionsCollisionGuard.cs | 127 +++++ 12 files changed, 969 insertions(+), 717 deletions(-) create mode 100644 src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs create mode 100644 tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj b/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj index a16b9c5e583..473ccd19845 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj @@ -37,6 +37,7 @@ + diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 22443e8164c..e131ccc351f 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -1662,35 +1662,36 @@ internal static string ToPascalCase(string name) /// /// /// - /// Names are qualified by the owning assembly so that they are a function of the capability - /// alone. Two assemblies can then never derive the same name — which is what lets a per-package - /// API export be projected on its own and still agree with a projection over the whole app host, - /// and what keeps concatenated export fragments from redeclaring one interface with different - /// members. + /// Names stay unqualified unless the checked-in shipped ATS surface already has a real + /// cross-package collision for that unqualified name. That preserves the old public names for + /// the unique option bags while still making the known collision groups a function of the + /// capability alone. /// /// - /// The core hosting package keeps unqualified names. It is present in every scan, so its names - /// were never the ones at risk, and leaving them alone confines the rename to the packages that - /// actually needed it. Other packages carry an encoding of their full assembly name, so + /// The core hosting package keeps unqualified names even inside a collision group. Other + /// packages in those groups carry an encoding of their full assembly name, so /// Aspire.Hosting.Azure.EventHubs yields - /// Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions. See - /// for why the encoding has to be reversible rather - /// than simply stripping the punctuation or common prefixes. + /// Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions. The TypeScript + /// API compatibility path guards this selective list so a new cross-package collision cannot + /// silently preserve an unsafe unqualified name. /// /// internal static string GetOptionsInterfaceName(string methodName, string owningAssemblyName) { - // Strip type prefix if present (e.g., "EndpointReference.getExpression" -> "getExpression") - var simpleName = methodName.Contains('.') - ? methodName[(methodName.LastIndexOf('.') + 1)..] - : methodName; + var unqualifiedName = TypeScriptOptionsInterfaceNaming.GetUnqualifiedOptionsInterfaceName(methodName); + if (string.IsNullOrEmpty(owningAssemblyName) || + string.Equals(owningAssemblyName, AtsConstants.AspireHostingAssembly, StringComparison.Ordinal) || + !TypeScriptOptionsInterfaceNaming.RequiresPackageQualifier(unqualifiedName)) + { + return unqualifiedName; + } - return $"{GetOptionsInterfaceQualifier(owningAssemblyName)}{ToPascalCase(simpleName)}Options"; + return $"{GetOptionsInterfaceQualifier(owningAssemblyName)}{unqualifiedName}"; } /// - /// Derives the name-space prefix an assembly's options interfaces carry, or an empty string for - /// the core hosting package and for symbols whose owner could not be resolved. + /// Derives the name-space prefix an assembly's options interfaces carry when their unqualified + /// names are in a known collision group. /// /// /// diff --git a/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs b/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs new file mode 100644 index 00000000000..b339cf871ca --- /dev/null +++ b/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.Shared.CodeGeneration; + +internal static class TypeScriptOptionsInterfaceNaming +{ + // These are the duplicate unqualified names in the checked-in shipped ATS surface. Keep unique + // names unqualified for compatibility; when the TypeScript API compatibility guard finds a new + // duplicate, add that name here so non-core packages move to package-qualified names together. + internal static IReadOnlySet PackageQualifiedOptionsInterfaceNames { get; } = + new HashSet(StringComparer.Ordinal) + { + "AddCertManagerOptions", + "AddDatabaseOptions", + "AddHubOptions", + "RunAsContainerOptions", + "RunAsEmulatorOptions", + "WithAccessKeyAuthenticationOptions", + "WithDashboardOptions", + "WithDataBindMountOptions", + "WithDataVolumeOptions", + "WithForwardedHeadersOptions", + "WithHttpsUpgradeOptions", + "WithOtlpExporterOptions", + "WithPersistenceOptions", + "WithPostgresMcpOptions" + }; + + internal static bool RequiresPackageQualifier(string unqualifiedInterfaceName) + => PackageQualifiedOptionsInterfaceNames.Contains(unqualifiedInterfaceName); + + internal static string GetUnqualifiedOptionsInterfaceName(string methodName) + { + var simpleName = methodName.Contains('.') + ? methodName[(methodName.LastIndexOf('.') + 1)..] + : methodName; + + return $"{ToPascalCase(simpleName)}Options"; + } + + private static string ToPascalCase(string name) + { + if (string.IsNullOrEmpty(name)) + { + return name; + } + + if (char.IsUpper(name[0])) + { + return name; + } + + return char.ToUpperInvariant(name[0]) + name[1..]; + } +} diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 22ad472de65..2616537f2c0 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2053,29 +2053,29 @@ AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] member => member.Name == "withOptionalString"); Assert.Collection( withOptionalString.Parameters, - parameter => AssertParameter(parameter, "options", $"{TestOptionsPrefix}WithOptionalStringOptions", isOptional: true)); + parameter => AssertParameter(parameter, "options", "WithOptionalStringOptions", isOptional: true)); var withOptionsCollision = Assert.Single( testRedisResource.Members, member => member.Name == "withOptionsCollision"); Assert.Equal( - $"withOptionsCollision(options: string, optionsBag: string, _optionsBag?: {TestOptionsPrefix}WithOptionsCollisionOptions): Promise", + "withOptionsCollision(options: string, optionsBag: string, _optionsBag?: WithOptionsCollisionOptions): Promise", withOptionsCollision.Declaration); Assert.Collection( withOptionsCollision.Parameters, parameter => AssertParameter(parameter, "options", "string", isOptional: false, "Required options value."), parameter => AssertParameter(parameter, "optionsBag", "string", isOptional: false, "Required options bag value."), - parameter => AssertParameter(parameter, "_optionsBag", $"{TestOptionsPrefix}WithOptionsCollisionOptions", isOptional: true)); + parameter => AssertParameter(parameter, "_optionsBag", "WithOptionsCollisionOptions", isOptional: true)); var withOptionalOptionsField = Assert.Single( testRedisResource.Members, member => member.Name == "withOptionalOptionsField"); Assert.Equal( - $"withOptionalOptionsField(options?: {TestOptionsPrefix}WithOptionalOptionsFieldOptions): Promise", + "withOptionalOptionsField(options?: WithOptionalOptionsFieldOptions): Promise", withOptionalOptionsField.Declaration); Assert.Collection( withOptionalOptionsField.Parameters, - parameter => AssertParameter(parameter, "options", $"{TestOptionsPrefix}WithOptionalOptionsFieldOptions", isOptional: true)); + parameter => AssertParameter(parameter, "options", "WithOptionalOptionsFieldOptions", isOptional: true)); var withDirectOptionsAndCancellation = Assert.Single( testRedisResource.Members, @@ -2097,7 +2097,7 @@ AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] Assert.Contains(withOptionalOptionsField.Declaration, testRedisResourceMembers); Assert.Contains(withDirectOptionsAndCancellation.Declaration, testRedisResourceMembers); Assert.Contains( - $$"""async withOptionalOptionsField(optionsBag?: {{TestOptionsPrefix}}WithOptionalOptionsFieldOptions): Promise {""", + "async withOptionalOptionsField(optionsBag?: WithOptionalOptionsFieldOptions): Promise {", generatedSource); Assert.Contains("const options = optionsBag?.options;", generatedSource); Assert.DoesNotContain("const options = options?.options;", generatedSource); @@ -2673,6 +2673,14 @@ public void OptionsInterfaceQualifiersUseTheFullAssemblyName() Assert.Equal(3, new[] { hostingRedis, aspireRedis, bareRedis }.Distinct(StringComparer.Ordinal).Count()); } + [Fact] + public void UniqueOptionsInterfaceNamesStayUnqualified() + { + var name = TypeScriptApiProjector.GetOptionsInterfaceName("withUniqueSetting", "Aspire.Hosting.Redis"); + + Assert.Equal("WithUniqueSettingOptions", name); + } + /// /// An options interface is documented by, and keyed to, the assembly whose capability produced /// it rather than the package the export was requested for. diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts index 5dde77ebe44..13ee4ae62db 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts @@ -172,50 +172,50 @@ export namespace TestConfigs { // Options Interfaces // ============================================================================ -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions { +export interface AddTestChildDatabaseOptions { databaseName?: string; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions { +export interface AddTestRedisOptions { port?: number; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { + name?: string; + isReadOnly?: boolean; +} + +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { + mode?: TestPersistenceMode; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions { +export interface GetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { - name?: string; - isReadOnly?: boolean; +export interface WaitForReadyAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions { +export interface WithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions { +export interface WithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions { +export interface WithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions { +export interface WithOptionalStringOptions { value?: string; enabled?: boolean; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { - mode?: TestPersistenceMode; -} - // ============================================================================ // TestCallbackContext // ============================================================================ @@ -667,7 +667,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -679,7 +679,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addTestRedis(name, options)), this._client); } @@ -769,7 +769,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -784,7 +784,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -820,12 +820,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -837,7 +837,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withOptionalString(options)), this._client); } @@ -1380,7 +1380,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -1440,11 +1440,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -1471,7 +1471,7 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. @@ -1481,7 +1481,7 @@ export interface TestRedisResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1502,7 +1502,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1529,14 +1529,14 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** @@ -1556,12 +1556,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1576,7 +1576,7 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. @@ -1586,7 +1586,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -1607,7 +1607,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -1634,14 +1634,14 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** @@ -1661,12 +1661,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -1700,7 +1700,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -1741,7 +1741,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -1880,7 +1880,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2056,7 +2056,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { + async getStatusAsync(options?: GetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2089,7 +2089,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -2219,7 +2219,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2241,7 +2241,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -2296,7 +2296,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return this._promise.then(onfulfilled, onrejected); } - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } @@ -2304,7 +2304,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -2340,7 +2340,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -2388,7 +2388,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { + getStatusAsync(options?: GetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -2396,7 +2396,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -2424,11 +2424,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -2452,7 +2452,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2467,7 +2467,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2500,12 +2500,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2517,7 +2517,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -2532,7 +2532,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -2565,12 +2565,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -2602,7 +2602,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -2708,7 +2708,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -2951,7 +2951,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -2973,7 +2973,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3028,7 +3028,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3052,7 +3052,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3112,11 +3112,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -3140,7 +3140,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3153,7 +3153,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3182,12 +3182,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3199,7 +3199,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -3212,7 +3212,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -3241,12 +3241,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -3278,7 +3278,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -3364,7 +3364,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -3577,7 +3577,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -3599,7 +3599,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -3654,7 +3654,7 @@ class ResourcePromiseImpl implements ResourcePromise { return this._promise.then(onfulfilled, onrejected); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -3674,7 +3674,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -3726,11 +3726,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index 3cc0ed87d56..0d5d4acca9f 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -1,12 +1,12 @@ // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource export interface CSharpAppResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -20,21 +20,21 @@ export interface CSharpAppResource { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise export interface CSharpAppResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; withConfig(config: TestConfigDto): CSharpAppResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; withCreatedAt(createdAt: string): CSharpAppResourcePromise; withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; withStatus(status: TestResourceStatus): CSharpAppResourcePromise; withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; @@ -48,20 +48,20 @@ export interface CSharpAppResourcePromise { withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource export interface ContainerRegistryResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -74,20 +74,20 @@ export interface ContainerRegistryResource { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise export interface ContainerRegistryResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; @@ -100,21 +100,21 @@ export interface ContainerRegistryResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource export interface ContainerResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -128,21 +128,21 @@ export interface ContainerResource { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise export interface ContainerResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; withConfig(config: TestConfigDto): ContainerResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; withCreatedAt(createdAt: string): ContainerResourcePromise; withModifiedAt(modifiedAt: string): ContainerResourcePromise; withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; withStatus(status: TestResourceStatus): ContainerResourcePromise; withNestedConfig(config: TestNestedDto): ContainerResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; @@ -156,33 +156,33 @@ export interface ContainerResourcePromise { withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder export interface DistributedApplicationBuilder { - addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise export interface DistributedApplicationBuilderPromise { - addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; addTestVault(name: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource export interface DotnetToolResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -196,21 +196,21 @@ export interface DotnetToolResource { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise export interface DotnetToolResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; withConfig(config: TestConfigDto): DotnetToolResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; withCreatedAt(createdAt: string): DotnetToolResourcePromise; withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; withStatus(status: TestResourceStatus): DotnetToolResourcePromise; withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; @@ -224,21 +224,21 @@ export interface DotnetToolResourcePromise { withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource export interface ExecutableResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -252,21 +252,21 @@ export interface ExecutableResource { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise export interface ExecutableResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; withConfig(config: TestConfigDto): ExecutableResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; withCreatedAt(createdAt: string): ExecutableResourcePromise; withModifiedAt(modifiedAt: string): ExecutableResourcePromise; withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; withStatus(status: TestResourceStatus): ExecutableResourcePromise; withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; @@ -280,20 +280,20 @@ export interface ExecutableResourcePromise { withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource export interface ExternalServiceResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -306,20 +306,20 @@ export interface ExternalServiceResource { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise export interface ExternalServiceResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; withConfig(config: TestConfigDto): ExternalServiceResourcePromise; withCreatedAt(createdAt: string): ExternalServiceResourcePromise; withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; @@ -332,20 +332,20 @@ export interface ExternalServiceResourcePromise { withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource export interface ParameterResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -358,20 +358,20 @@ export interface ParameterResource { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise export interface ParameterResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; withConfig(config: TestConfigDto): ParameterResourcePromise; withCreatedAt(createdAt: string): ParameterResourcePromise; withModifiedAt(modifiedAt: string): ParameterResourcePromise; withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; withStatus(status: TestResourceStatus): ParameterResourcePromise; withNestedConfig(config: TestNestedDto): ParameterResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; @@ -384,21 +384,21 @@ export interface ParameterResourcePromise { withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource export interface ProjectResource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -412,21 +412,21 @@ export interface ProjectResource { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise export interface ProjectResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; withConfig(config: TestConfigDto): ProjectResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; withCreatedAt(createdAt: string): ProjectResourcePromise; withModifiedAt(modifiedAt: string): ProjectResourcePromise; withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; withStatus(status: TestResourceStatus): ProjectResourcePromise; withNestedConfig(config: TestNestedDto): ProjectResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; @@ -440,20 +440,20 @@ export interface ProjectResourcePromise { withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource export interface Resource { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -466,20 +466,20 @@ export interface Resource { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise export interface ResourcePromise { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; withConfig(config: TestConfigDto): ResourcePromise; withCreatedAt(createdAt: string): ResourcePromise; withModifiedAt(modifiedAt: string): ResourcePromise; withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; withStatus(status: TestResourceStatus): ResourcePromise; withNestedConfig(config: TestNestedDto): ResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; @@ -492,8 +492,8 @@ export interface ResourcePromise { withMergeLabelCategorized(label: string, category: string): ResourcePromise; withMergeEndpoint(endpointName: string, port: number): ResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; } @@ -586,13 +586,13 @@ export interface TestCollectionContextPromise extends PromiseLike Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -606,21 +606,21 @@ export interface TestDatabaseResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise export interface TestDatabaseResourcePromise extends PromiseLike { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; withConfig(config: TestConfigDto): TestDatabaseResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; withCreatedAt(createdAt: string): TestDatabaseResourcePromise; withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; @@ -634,8 +634,8 @@ export interface TestDatabaseResourcePromise extends PromiseLike>; getMetadata(): Promise>; @@ -669,7 +669,7 @@ export interface TestRedisResource extends ResourceBuilderBase { withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -681,26 +681,26 @@ export interface TestRedisResource extends ResourceBuilderBase { withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise export interface TestRedisResourcePromise extends PromiseLike { - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; withConfig(config: TestConfigDto): TestRedisResourcePromise; getTags(): Promise>; getMetadata(): Promise>; @@ -709,7 +709,7 @@ export interface TestRedisResourcePromise extends PromiseLike withCreatedAt(createdAt: string): TestRedisResourcePromise; withModifiedAt(modifiedAt: string): TestRedisResourcePromise; withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; withStatus(status: TestResourceStatus): TestRedisResourcePromise; withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; @@ -721,17 +721,17 @@ export interface TestRedisResourcePromise extends PromiseLike withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; withEndpoints(endpoints: string[]): TestRedisResourcePromise; withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; } @@ -758,13 +758,13 @@ export interface TestResourceContextPromise extends PromiseLike Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -779,21 +779,21 @@ export interface TestVaultResource extends ResourceBuilderBase { withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise export interface TestVaultResourcePromise extends PromiseLike { - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; withConfig(config: TestConfigDto): TestVaultResourcePromise; testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; withCreatedAt(createdAt: string): TestVaultResourcePromise; withModifiedAt(modifiedAt: string): TestVaultResourcePromise; withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; withStatus(status: TestResourceStatus): TestVaultResourcePromise; withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; @@ -808,66 +808,66 @@ export interface TestVaultResourcePromise extends PromiseLike withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions +export interface AddTestChildDatabaseOptions { databaseName?: string; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions +export interface AddTestRedisOptions { port?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { + name?: string; + isReadOnly?: boolean; +} + +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { + mode?: TestPersistenceMode; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions +export interface GetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { - name?: string; - isReadOnly?: boolean; +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions +export interface WaitForReadyAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions +export interface WithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions +export interface WithMergeLoggingPathOptions { enableConsole?: boolean; maxFiles?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions +export interface WithOptionalCallbackOptions { callback?: (arg: TestCallbackContext) => Promise; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions +export interface WithOptionalStringOptions { value?: string; enabled?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { - mode?: TestPersistenceMode; -} - // Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle export type CommandLineArgsCallbackContextHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.CommandLineArgsCallbackContext'>; diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index 0d976c57dda..c5a6dd2042b 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -24,14 +24,14 @@ "id": "method:CSharpAppResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "CSharpAppResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -120,14 +120,14 @@ "id": "method:CSharpAppResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "CSharpAppResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -364,7 +364,7 @@ "id": "method:CSharpAppResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging", @@ -376,7 +376,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -385,7 +385,7 @@ "id": "method:CSharpAppResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "CSharpAppResourcePromise", "summary": "Configures resource logging with file path", @@ -402,7 +402,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -491,14 +491,14 @@ "id": "method:ContainerRegistryResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerRegistryResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -571,14 +571,14 @@ "id": "method:ContainerRegistryResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -799,7 +799,7 @@ "id": "method:ContainerRegistryResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging", @@ -811,7 +811,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -820,7 +820,7 @@ "id": "method:ContainerRegistryResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerRegistryResourcePromise", "summary": "Configures resource logging with file path", @@ -837,7 +837,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -927,14 +927,14 @@ "id": "method:ContainerResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ContainerResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -1023,14 +1023,14 @@ "id": "method:ContainerResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ContainerResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -1267,7 +1267,7 @@ "id": "method:ContainerResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging", @@ -1279,7 +1279,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -1288,7 +1288,7 @@ "id": "method:ContainerResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ContainerResourcePromise", "summary": "Configures resource logging with file path", @@ -1305,7 +1305,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -1392,7 +1392,7 @@ "id": "method:DistributedApplicationBuilder.addTestRedis", "kind": "method", "name": "addTestRedis", - "declaration": "addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise", + "declaration": "addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestRedis", "returnType": "TestRedisResourcePromise", "summary": "Adds a test Redis resource from ATS documentation.", @@ -1405,7 +1405,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", + "type": "AddTestRedisOptions", "optional": true } ] @@ -1443,14 +1443,14 @@ "id": "method:DotnetToolResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "DotnetToolResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -1539,14 +1539,14 @@ "id": "method:DotnetToolResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "DotnetToolResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -1783,7 +1783,7 @@ "id": "method:DotnetToolResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging", @@ -1795,7 +1795,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -1804,7 +1804,7 @@ "id": "method:DotnetToolResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "DotnetToolResourcePromise", "summary": "Configures resource logging with file path", @@ -1821,7 +1821,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -1912,14 +1912,14 @@ "id": "method:ExecutableResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExecutableResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -2008,14 +2008,14 @@ "id": "method:ExecutableResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExecutableResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -2252,7 +2252,7 @@ "id": "method:ExecutableResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging", @@ -2264,7 +2264,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -2273,7 +2273,7 @@ "id": "method:ExecutableResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExecutableResourcePromise", "summary": "Configures resource logging with file path", @@ -2290,7 +2290,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -2379,14 +2379,14 @@ "id": "method:ExternalServiceResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ExternalServiceResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -2459,14 +2459,14 @@ "id": "method:ExternalServiceResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ExternalServiceResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -2687,7 +2687,7 @@ "id": "method:ExternalServiceResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging", @@ -2699,7 +2699,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -2708,7 +2708,7 @@ "id": "method:ExternalServiceResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ExternalServiceResourcePromise", "summary": "Configures resource logging with file path", @@ -2725,7 +2725,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -2815,14 +2815,14 @@ "id": "method:ParameterResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ParameterResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -2895,14 +2895,14 @@ "id": "method:ParameterResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ParameterResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -3123,7 +3123,7 @@ "id": "method:ParameterResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging", @@ -3135,7 +3135,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -3144,7 +3144,7 @@ "id": "method:ParameterResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ParameterResourcePromise", "summary": "Configures resource logging with file path", @@ -3161,7 +3161,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -3251,14 +3251,14 @@ "id": "method:ProjectResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ProjectResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -3347,14 +3347,14 @@ "id": "method:ProjectResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ProjectResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -3591,7 +3591,7 @@ "id": "method:ProjectResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging", @@ -3603,7 +3603,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -3612,7 +3612,7 @@ "id": "method:ProjectResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ProjectResourcePromise", "summary": "Configures resource logging with file path", @@ -3629,7 +3629,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -3719,14 +3719,14 @@ "id": "method:Resource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "ResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -3799,14 +3799,14 @@ "id": "method:Resource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "ResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -4027,7 +4027,7 @@ "id": "method:Resource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "ResourcePromise", "summary": "Configures resource logging", @@ -4039,7 +4039,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -4048,7 +4048,7 @@ "id": "method:Resource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "ResourcePromise", "summary": "Configures resource logging with file path", @@ -4065,7 +4065,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -4473,14 +4473,14 @@ "id": "method:TestDatabaseResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestDatabaseResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -4569,14 +4569,14 @@ "id": "method:TestDatabaseResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestDatabaseResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -4813,7 +4813,7 @@ "id": "method:TestDatabaseResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging", @@ -4825,7 +4825,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -4834,7 +4834,7 @@ "id": "method:TestDatabaseResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestDatabaseResourcePromise", "summary": "Configures resource logging with file path", @@ -4851,7 +4851,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -4996,7 +4996,7 @@ "id": "method:TestRedisResource.addTestChildDatabase", "kind": "method", "name": "addTestChildDatabase", - "declaration": "addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise", + "declaration": "addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestChildDatabase", "returnType": "TestDatabaseResourcePromise", "summary": "Adds a child database to a test Redis resource", @@ -5009,7 +5009,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", + "type": "AddTestChildDatabaseOptions", "optional": true } ] @@ -5034,14 +5034,14 @@ "id": "method:TestRedisResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestRedisResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -5164,14 +5164,14 @@ "id": "method:TestRedisResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestRedisResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -5349,14 +5349,14 @@ "id": "method:TestRedisResource.getStatusAsync", "kind": "method", "name": "getStatusAsync", - "declaration": "getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E", + "declaration": "getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getStatusAsync", "returnType": "Promise\u003Cstring\u003E", "summary": "Gets the status of the resource asynchronously", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", + "type": "GetStatusAsyncOptions", "optional": true } ] @@ -5381,7 +5381,7 @@ "id": "method:TestRedisResource.waitForReadyAsync", "kind": "method", "name": "waitForReadyAsync", - "declaration": "waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", + "declaration": "waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync", "returnType": "Promise\u003Cboolean\u003E", "summary": "Waits for the resource to be ready", @@ -5393,7 +5393,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", + "type": "WaitForReadyAsyncOptions", "optional": true } ] @@ -5518,7 +5518,7 @@ "id": "method:TestRedisResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging", @@ -5530,7 +5530,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -5539,7 +5539,7 @@ "id": "method:TestRedisResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestRedisResourcePromise", "summary": "Configures resource logging with file path", @@ -5556,7 +5556,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -5704,14 +5704,14 @@ "id": "method:TestVaultResource.withOptionalString", "kind": "method", "name": "withOptionalString", - "declaration": "withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise", + "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", "returnType": "TestVaultResourcePromise", "summary": "Adds an optional string parameter", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "type": "WithOptionalStringOptions", "optional": true } ] @@ -5800,14 +5800,14 @@ "id": "method:TestVaultResource.withOptionalCallback", "kind": "method", "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise", + "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", "returnType": "TestVaultResourcePromise", "summary": "Configures with optional callback", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "type": "WithOptionalCallbackOptions", "optional": true } ] @@ -6060,7 +6060,7 @@ "id": "method:TestVaultResource.withMergeLogging", "kind": "method", "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise", + "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging", @@ -6072,7 +6072,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "type": "WithMergeLoggingOptions", "optional": true } ] @@ -6081,7 +6081,7 @@ "id": "method:TestVaultResource.withMergeLoggingPath", "kind": "method", "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise", + "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", "returnType": "TestVaultResourcePromise", "summary": "Configures resource logging with file path", @@ -6098,7 +6098,7 @@ }, { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "type": "WithMergeLoggingPathOptions", "optional": true } ] @@ -6173,15 +6173,15 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", + "id": "options:AddTestChildDatabaseOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", + "name": "AddTestChildDatabaseOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", + "declaration": "export interface AddTestChildDatabaseOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions.databaseName", + "id": "property:AddTestChildDatabaseOptions.databaseName", "kind": "property", "name": "databaseName", "declaration": "databaseName?: string" @@ -6189,15 +6189,15 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", + "id": "options:AddTestRedisOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", + "name": "AddTestRedisOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", + "declaration": "export interface AddTestRedisOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions.port", + "id": "property:AddTestRedisOptions.port", "kind": "property", "name": "port", "declaration": "port?: number" @@ -6205,75 +6205,91 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions.cancellationToken", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.name", "kind": "property", - "name": "cancellationToken", - "declaration": "cancellationToken?: AbortSignal | CancellationToken" + "name": "name", + "declaration": "name?: string" + }, + { + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.isReadOnly", + "kind": "property", + "name": "isReadOnly", + "declaration": "isReadOnly?: boolean" } ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions.cancellationToken", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions.mode", "kind": "property", - "name": "cancellationToken", - "declaration": "cancellationToken?: AbortSignal | CancellationToken" + "name": "mode", + "declaration": "mode?: TestPersistenceMode" } ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "id": "options:GetStatusAsyncOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "name": "GetStatusAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/GetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "declaration": "export interface GetStatusAsyncOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.name", + "id": "property:GetStatusAsyncOptions.cancellationToken", "kind": "property", - "name": "name", - "declaration": "name?: string" - }, + "name": "cancellationToken", + "declaration": "cancellationToken?: AbortSignal | CancellationToken" + } + ] + }, + { + "id": "options:WaitForReadyAsyncOptions", + "kind": "options", + "name": "WaitForReadyAsyncOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WaitForReadyAsyncOptions", + "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", + "declaration": "export interface WaitForReadyAsyncOptions", + "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.isReadOnly", + "id": "property:WaitForReadyAsyncOptions.cancellationToken", "kind": "property", - "name": "isReadOnly", - "declaration": "isReadOnly?: boolean" + "name": "cancellationToken", + "declaration": "cancellationToken?: AbortSignal | CancellationToken" } ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "id": "options:WithMergeLoggingOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "name": "WithMergeLoggingOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "declaration": "export interface WithMergeLoggingOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions.enableConsole", + "id": "property:WithMergeLoggingOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions.maxFiles", + "id": "property:WithMergeLoggingOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6281,21 +6297,21 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "id": "options:WithMergeLoggingPathOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "name": "WithMergeLoggingPathOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "declaration": "export interface WithMergeLoggingPathOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions.enableConsole", + "id": "property:WithMergeLoggingPathOptions.enableConsole", "kind": "property", "name": "enableConsole", "declaration": "enableConsole?: boolean" }, { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions.maxFiles", + "id": "property:WithMergeLoggingPathOptions.maxFiles", "kind": "property", "name": "maxFiles", "declaration": "maxFiles?: number" @@ -6303,15 +6319,15 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "id": "options:WithOptionalCallbackOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "name": "WithOptionalCallbackOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "declaration": "export interface WithOptionalCallbackOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions.callback", + "id": "property:WithOptionalCallbackOptions.callback", "kind": "property", "name": "callback", "declaration": "callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E" @@ -6319,42 +6335,26 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "id": "options:WithOptionalStringOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "name": "WithOptionalStringOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "declaration": "export interface WithOptionalStringOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions.value", + "id": "property:WithOptionalStringOptions.value", "kind": "property", "name": "value", "declaration": "value?: string" }, { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions.enabled", + "id": "property:WithOptionalStringOptions.enabled", "kind": "property", "name": "enabled", "declaration": "enabled?: boolean" } ] - }, - { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", - "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", - "members": [ - { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions.mode", - "kind": "property", - "name": "mode", - "declaration": "mode?: TestPersistenceMode" - } - ] } ] } @@ -6363,102 +6363,102 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResource {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" + "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" + "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" + "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" + "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResource {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" + "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResource {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" + "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResource {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" + "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResource {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" + "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResource {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" + "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Resource {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface Resource {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourcePromise {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" + "content": "export interface ResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString", @@ -6528,12 +6528,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" + "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext", @@ -6548,12 +6548,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", @@ -6568,62 +6568,62 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" + "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions {\n databaseName?: string;\n}" + "content": "export interface AddTestChildDatabaseOptions {\n databaseName?: string;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions {\n port?: number;\n}" + "content": "export interface AddTestRedisOptions {\n port?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" + "content": "export interface GetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface WaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" + "content": "export interface WithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" + "content": "export interface WithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" + "content": "export interface WithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" + "content": "export interface WithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" }, { "id": "Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle", diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts index 26d6f818caf..be68910f2e3 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts @@ -1516,6 +1516,14 @@ export interface AddStepOptions { requiredBy?: string[]; } +export interface AddTestChildDatabaseOptions { + databaseName?: string; +} + +export interface AddTestRedisOptions { + port?: number; +} + export interface AppendFormattedOptions { /** The format to be applied to the value. e.g., "uri" */ format?: string; @@ -1530,46 +1538,11 @@ export interface ArgOptions { defaultValue?: string; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions { - databaseName?: string; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions { - port?: number; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; -} - export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions { - enableConsole?: boolean; - maxFiles?: number; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions { - enableConsole?: boolean; - maxFiles?: number; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions { - callback?: (arg: TestCallbackContext) => Promise; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions { - value?: string; - enabled?: boolean; -} - export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { mode?: TestPersistenceMode; } @@ -1675,6 +1648,10 @@ export interface FromOptions { stageName?: string; } +export interface GetStatusAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; +} + export interface GetValueAsyncOptions { /** The cancellation token. */ cancellationToken?: AbortSignal | CancellationToken; @@ -1723,6 +1700,10 @@ export interface WaitForOptions { waitBehavior?: WaitBehavior; } +export interface WaitForReadyAsyncOptions { + cancellationToken?: AbortSignal | CancellationToken; +} + export interface WaitForResourceStateOptions { targetState?: string; } @@ -1886,6 +1867,25 @@ export interface WithMcpServerOptions { endpointName?: string; } +export interface WithMergeLoggingOptions { + enableConsole?: boolean; + maxFiles?: number; +} + +export interface WithMergeLoggingPathOptions { + enableConsole?: boolean; + maxFiles?: number; +} + +export interface WithOptionalCallbackOptions { + callback?: (arg: TestCallbackContext) => Promise; +} + +export interface WithOptionalStringOptions { + value?: string; + enabled?: boolean; +} + export interface WithOtlpExporterOptions { protocol?: OtlpProtocol; } @@ -10946,7 +10946,7 @@ export interface DistributedApplicationBuilder { * @param options Additional options. * @returns The ATS test Redis resource builder. */ - addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise; + addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; /** Adds a test vault resource */ addTestVault(name: string): TestVaultResourcePromise; } @@ -11167,7 +11167,7 @@ export interface DistributedApplicationBuilderPromise extends PromiseLike obj.addHealthCheck(name, check)), this._client); } - addTestRedis(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestRedisOptions): TestRedisResourcePromise { + addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.addTestRedis(name, options)), this._client); } @@ -14688,7 +14688,7 @@ export interface ContainerRegistryResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; /** Sets the created timestamp */ @@ -14701,7 +14701,7 @@ export interface ContainerRegistryResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; /** Configures with nested DTO */ @@ -14730,12 +14730,12 @@ export interface ContainerRegistryResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; /** Configures a route with middleware */ @@ -15005,7 +15005,7 @@ export interface ContainerRegistryResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerRegistryResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -16508,7 +16508,7 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerRegistryResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -16560,11 +16560,11 @@ class ContainerRegistryResourcePromiseImpl implements ContainerRegistryResourceP return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerRegistryResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerRegistryResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise { return new ContainerRegistryResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -17335,7 +17335,7 @@ export interface ContainerResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -17350,7 +17350,7 @@ export interface ContainerResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -17381,12 +17381,12 @@ export interface ContainerResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -18144,7 +18144,7 @@ export interface ContainerResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ContainerResourcePromise; /** Configures environment with callback (test version) */ @@ -18159,7 +18159,7 @@ export interface ContainerResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ContainerResourcePromise; /** Configures with nested DTO */ @@ -18190,12 +18190,12 @@ export interface ContainerResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; /** Configures a route with middleware */ @@ -20543,7 +20543,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ContainerResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -20649,7 +20649,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise { const callback = options?.callback; return new ContainerResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -20877,7 +20877,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -20899,7 +20899,7 @@ class ContainerResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ContainerResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -21318,7 +21318,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ContainerResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -21342,7 +21342,7 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ContainerResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -21398,11 +21398,11 @@ class ContainerResourcePromiseImpl implements ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ContainerResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ContainerResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise { return new ContainerResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -21987,7 +21987,7 @@ export interface CSharpAppResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22002,7 +22002,7 @@ export interface CSharpAppResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22033,12 +22033,12 @@ export interface CSharpAppResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -22611,7 +22611,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): CSharpAppResourcePromise; /** Configures environment with callback (test version) */ @@ -22626,7 +22626,7 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): CSharpAppResourcePromise; /** Configures with nested DTO */ @@ -22657,12 +22657,12 @@ export interface CSharpAppResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; /** Configures a route with middleware */ @@ -24569,7 +24569,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise { const value = options?.value; const enabled = options?.enabled; return new CSharpAppResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -24675,7 +24675,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise { const callback = options?.callback; return new CSharpAppResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -24903,7 +24903,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -24925,7 +24925,7 @@ class CSharpAppResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new CSharpAppResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -25276,7 +25276,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): CSharpAppResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -25300,7 +25300,7 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): CSharpAppResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -25356,11 +25356,11 @@ class CSharpAppResourcePromiseImpl implements CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): CSharpAppResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): CSharpAppResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise { return new CSharpAppResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -25967,7 +25967,7 @@ export interface DotnetToolResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): DotnetToolResourcePromise; /** Configures environment with callback (test version) */ @@ -25982,7 +25982,7 @@ export interface DotnetToolResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): DotnetToolResourcePromise; /** Configures with nested DTO */ @@ -26013,12 +26013,12 @@ export interface DotnetToolResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; /** Configures a route with middleware */ @@ -26613,7 +26613,7 @@ export interface DotnetToolResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): DotnetToolResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -29389,7 +29389,7 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): DotnetToolResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -29445,11 +29445,11 @@ class DotnetToolResourcePromiseImpl implements DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): DotnetToolResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): DotnetToolResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise { return new DotnetToolResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -30030,7 +30030,7 @@ export interface ExecutableResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExecutableResourcePromise; /** Configures environment with callback (test version) */ @@ -30045,7 +30045,7 @@ export interface ExecutableResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExecutableResourcePromise; /** Configures with nested DTO */ @@ -30076,12 +30076,12 @@ export interface ExecutableResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; /** Configures a route with middleware */ @@ -30643,7 +30643,7 @@ export interface ExecutableResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExecutableResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -33291,7 +33291,7 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExecutableResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -33347,11 +33347,11 @@ class ExecutableResourcePromiseImpl implements ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExecutableResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExecutableResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise { return new ExecutableResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -33638,7 +33638,7 @@ export interface ExternalServiceResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ExternalServiceResourcePromise; /** Sets the created timestamp */ @@ -33651,7 +33651,7 @@ export interface ExternalServiceResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; /** Configures with nested DTO */ @@ -33680,12 +33680,12 @@ export interface ExternalServiceResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; /** Configures a route with middleware */ @@ -33960,7 +33960,7 @@ export interface ExternalServiceResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ExternalServiceResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -35491,7 +35491,7 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ExternalServiceResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -35543,11 +35543,11 @@ class ExternalServiceResourcePromiseImpl implements ExternalServiceResourcePromi return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ExternalServiceResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ExternalServiceResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise { return new ExternalServiceResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -35843,7 +35843,7 @@ export interface ParameterResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -35856,7 +35856,7 @@ export interface ParameterResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -35885,12 +35885,12 @@ export interface ParameterResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -36173,7 +36173,7 @@ export interface ParameterResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ParameterResourcePromise; /** Sets the created timestamp */ @@ -36186,7 +36186,7 @@ export interface ParameterResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ParameterResourcePromise; /** Configures with nested DTO */ @@ -36215,12 +36215,12 @@ export interface ParameterResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; /** Configures a route with middleware */ @@ -37182,7 +37182,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ParameterResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -37268,7 +37268,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise { const callback = options?.callback; return new ParameterResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -37481,7 +37481,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -37503,7 +37503,7 @@ class ParameterResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ParameterResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -37706,7 +37706,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ParameterResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -37726,7 +37726,7 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ParameterResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -37778,11 +37778,11 @@ class ParameterResourcePromiseImpl implements ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ParameterResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ParameterResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise { return new ParameterResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -38368,7 +38368,7 @@ export interface ProjectResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -38383,7 +38383,7 @@ export interface ProjectResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -38414,12 +38414,12 @@ export interface ProjectResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -38992,7 +38992,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ProjectResourcePromise; /** Configures environment with callback (test version) */ @@ -39007,7 +39007,7 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ProjectResourcePromise; /** Configures with nested DTO */ @@ -39038,12 +39038,12 @@ export interface ProjectResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; /** Configures a route with middleware */ @@ -40951,7 +40951,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ProjectResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -41057,7 +41057,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise { const callback = options?.callback; return new ProjectResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -41285,7 +41285,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -41307,7 +41307,7 @@ class ProjectResourceImpl extends ResourceBuilderBase imp * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ProjectResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -41658,7 +41658,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ProjectResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -41682,7 +41682,7 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ProjectResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -41738,11 +41738,11 @@ class ProjectResourcePromiseImpl implements ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ProjectResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ProjectResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise { return new ProjectResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -42512,7 +42512,7 @@ export interface TestDatabaseResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestDatabaseResourcePromise; /** Configures environment with callback (test version) */ @@ -42527,7 +42527,7 @@ export interface TestDatabaseResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; /** Configures with nested DTO */ @@ -42558,12 +42558,12 @@ export interface TestDatabaseResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; /** Configures a route with middleware */ @@ -43321,7 +43321,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestDatabaseResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -46518,7 +46518,7 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestDatabaseResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -46574,11 +46574,11 @@ class TestDatabaseResourcePromiseImpl implements TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestDatabaseResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestDatabaseResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -47373,7 +47373,7 @@ export interface TestRedisResource { * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. @@ -47383,7 +47383,7 @@ export interface TestRedisResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -47404,7 +47404,7 @@ export interface TestRedisResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -47431,14 +47431,14 @@ export interface TestRedisResource { * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** @@ -47458,12 +47458,12 @@ export interface TestRedisResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -48246,7 +48246,7 @@ export interface TestRedisResourcePromise extends PromiseLike * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise; + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; /** * Configures the Redis resource with persistence * @param options Additional options. @@ -48256,7 +48256,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestRedisResourcePromise; /** Gets the tags for the resource */ @@ -48277,7 +48277,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestRedisResourcePromise; /** Configures with nested DTO */ @@ -48304,14 +48304,14 @@ export interface TestRedisResourcePromise extends PromiseLike * Gets the status of the resource asynchronously * @param options Additional options. */ - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise; + getStatusAsync(options?: GetStatusAsyncOptions): Promise; /** Performs a cancellable operation */ withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; /** * Waits for the resource to be ready * @param options Additional options. */ - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise; + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; /** Tests multi-param callback destructuring */ withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; /** @@ -48331,12 +48331,12 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; /** Configures a route with middleware */ @@ -50745,7 +50745,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * returns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource). * @param options Additional options. */ - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { const databaseName = options?.databaseName; return new TestDatabaseResourcePromiseImpl(this._addTestChildDatabaseInternal(name, databaseName), this._client); } @@ -50786,7 +50786,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestRedisResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -50925,7 +50925,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { const callback = options?.callback; return new TestRedisResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -51101,7 +51101,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Gets the status of the resource asynchronously * @param options Additional options. */ - async getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { + async getStatusAsync(options?: GetStatusAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51134,7 +51134,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Waits for the resource to be ready * @param options Additional options. */ - async waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { + async waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { const cancellationToken = options?.cancellationToken; const rpcArgs: Record = { builder: this._handle, timeout }; if (cancellationToken !== undefined) rpcArgs.cancellationToken = CancellationToken.fromValue(cancellationToken); @@ -51264,7 +51264,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -51286,7 +51286,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestRedisResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -51717,7 +51717,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - addTestChildDatabase(name: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsAddTestChildDatabaseOptions): TestDatabaseResourcePromise { + addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } @@ -51725,7 +51725,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestRedisResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -51761,7 +51761,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestRedisResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -51809,7 +51809,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withEnvironmentVariables(variables)), this._client); } - getStatusAsync(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsGetStatusAsyncOptions): Promise { + getStatusAsync(options?: GetStatusAsyncOptions): Promise { return this._promise.then(obj => obj.getStatusAsync(options)); } @@ -51817,7 +51817,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withCancellableOperation(operation)), this._client); } - waitForReadyAsync(timeout: number, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWaitForReadyAsyncOptions): Promise { + waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise { return this._promise.then(obj => obj.waitForReadyAsync(timeout, options)); } @@ -51845,11 +51845,11 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestRedisResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestRedisResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -52619,7 +52619,7 @@ export interface TestVaultResource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -52634,7 +52634,7 @@ export interface TestVaultResource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -52667,12 +52667,12 @@ export interface TestVaultResource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -53430,7 +53430,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): TestVaultResourcePromise; /** Configures environment with callback (test version) */ @@ -53445,7 +53445,7 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): TestVaultResourcePromise; /** Configures with nested DTO */ @@ -53478,12 +53478,12 @@ export interface TestVaultResourcePromise extends PromiseLike * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; /** Configures a route with middleware */ @@ -55830,7 +55830,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { const value = options?.value; const enabled = options?.enabled; return new TestVaultResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -55936,7 +55936,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { const callback = options?.callback; return new TestVaultResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -56179,7 +56179,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -56201,7 +56201,7 @@ class TestVaultResourceImpl extends ResourceBuilderBase * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new TestVaultResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -56620,7 +56620,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): TestVaultResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -56644,7 +56644,7 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): TestVaultResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -56704,11 +56704,11 @@ class TestVaultResourcePromiseImpl implements TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): TestVaultResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): TestVaultResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise { return new TestVaultResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } @@ -57310,7 +57310,7 @@ export interface Resource { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57323,7 +57323,7 @@ export interface Resource { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57352,12 +57352,12 @@ export interface Resource { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -57627,7 +57627,7 @@ export interface ResourcePromise extends PromiseLike { * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise; + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; /** Configures the resource with a DTO */ withConfig(config: TestConfigDto): ResourcePromise; /** Sets the created timestamp */ @@ -57640,7 +57640,7 @@ export interface ResourcePromise extends PromiseLike { * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise; + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; /** Sets the resource status */ withStatus(status: TestResourceStatus): ResourcePromise; /** Configures with nested DTO */ @@ -57669,12 +57669,12 @@ export interface ResourcePromise extends PromiseLike { * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise; + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; /** * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise; + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; /** Configures a route */ withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; /** Configures a route with middleware */ @@ -58595,7 +58595,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Adds an optional string parameter * @param options Additional options. */ - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { const value = options?.value; const enabled = options?.enabled; return new ResourcePromiseImpl(this._withOptionalStringInternal(value, enabled), this._client); @@ -58681,7 +58681,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures with optional callback * @param options Additional options. */ - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { const callback = options?.callback; return new ResourcePromiseImpl(this._withOptionalCallbackInternal(callback), this._client); } @@ -58894,7 +58894,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging * @param options Additional options. */ - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingInternal(logLevel, enableConsole, maxFiles), this._client); @@ -58916,7 +58916,7 @@ class ResourceImpl extends ResourceBuilderBase implements Resou * Configures resource logging with file path * @param options Additional options. */ - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { const enableConsole = options?.enableConsole; const maxFiles = options?.maxFiles; return new ResourcePromiseImpl(this._withMergeLoggingPathInternal(logLevel, logPath, enableConsole, maxFiles), this._client); @@ -59111,7 +59111,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withContainerBuildOptions(callback)), this._client); } - withOptionalString(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalStringOptions): ResourcePromise { + withOptionalString(options?: WithOptionalStringOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalString(options)), this._client); } @@ -59131,7 +59131,7 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withCorrelationId(correlationId)), this._client); } - withOptionalCallback(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithOptionalCallbackOptions): ResourcePromise { + withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withOptionalCallback(options)), this._client); } @@ -59183,11 +59183,11 @@ class ResourcePromiseImpl implements ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeEndpointScheme(endpointName, port, scheme)), this._client); } - withMergeLogging(logLevel: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingOptions): ResourcePromise { + withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLogging(logLevel, options)), this._client); } - withMergeLoggingPath(logLevel: string, logPath: string, options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithMergeLoggingPathOptions): ResourcePromise { + withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise { return new ResourcePromiseImpl(this._promise.then(obj => obj.withMergeLoggingPath(logLevel, logPath, options)), this._client); } diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index 623851d5c2e..5cbd95202a9 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -323,6 +323,60 @@ public void RunnerIgnoresExcludedPackagesAndSuppressions() Assert.DoesNotContain("Unused suppressions", report, StringComparison.Ordinal); } + [Fact] + public void RunnerFailsWhenUnqualifiedOptionsInterfaceNamesCollide() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + WriteSurface(baselineRoot, "Pkg.One", """ + # Capabilities + Pkg.One/withShared(port?: number) -> void + """); + WriteSurface(baselineRoot, "Pkg.Two", """ + # Capabilities + Pkg.Two/withShared(host?: string) -> void + """); + WriteSurface(currentRoot, "Pkg.One", """ + # Capabilities + Pkg.One/withShared(port?: number) -> void + """); + WriteSurface(currentRoot, "Pkg.Two", """ + # Capabilities + Pkg.Two/withShared(host?: string) -> void + """); + + using var error = new StringWriter(); + var originalError = Console.Error; + try + { + Console.SetError(error); + + var exitCode = TypeScriptApiCompatRunner.Run(new CommandLineOptions( + baselineRoot, + currentRoot, + workspace.Path, + BaselineSuppressionsRoot: null, + ExcludedPackagesFile: null, + ReportPath: null, + GitHubAnnotations: false)); + + Assert.Equal(2, exitCode); + } + finally + { + Console.SetError(originalError); + } + + var message = error.ToString(); + Assert.Contains("Unqualified TypeScript options interface collision", message, StringComparison.Ordinal); + Assert.Contains("WithSharedOptions", message, StringComparison.Ordinal); + Assert.Contains("'Pkg.One'", message, StringComparison.Ordinal); + Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); + Assert.Contains("Remedy:", message, StringComparison.Ordinal); + } + private static void WriteSurface(string rootPath, string packageName, string content) { var apiDirectory = Path.Combine(rootPath, "src", packageName, "api"); diff --git a/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj b/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj index 2bb117d795c..2c3529be2c3 100644 --- a/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj +++ b/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj @@ -15,4 +15,8 @@ + + + + diff --git a/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs b/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs index 6d9216234c4..2dd4386923c 100644 --- a/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs +++ b/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs @@ -12,6 +12,7 @@ public static int Run(CommandLineOptions options) var excludedPackages = ExcludedPackageLoader.Load(options.ExcludedPackagesFile); var baseline = AtsSurfaceSet.Load(options.BaselinePath); var current = AtsSurfaceSet.Load(options.CurrentPath); + TypeScriptOptionsCollisionGuard.Validate(current); var diagnostics = AtsCompatibilityComparer.Compare(baseline, current, excludedPackages); var suppressionLoadResult = ApiCompatSuppressionLoader.Load(options.SuppressionsRoot); var baselineSuppressionLoadResult = options.BaselineSuppressionsRoot is null diff --git a/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs b/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs new file mode 100644 index 00000000000..ddc7bbdf505 --- /dev/null +++ b/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs @@ -0,0 +1,127 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text; +using Aspire.Shared.CodeGeneration; + +namespace TypeScriptApiCompat; + +internal static class TypeScriptOptionsCollisionGuard +{ + public static void Validate(AtsSurfaceSet surfaceSet) + { + var dtoTypeIds = surfaceSet.Surfaces.Values + .SelectMany(static surface => surface.DtoTypes.Keys) + .ToHashSet(StringComparer.Ordinal); + var candidates = new List(); + + foreach (var surface in surfaceSet.Surfaces.Values.OrderBy(static surface => surface.PackageName, StringComparer.Ordinal)) + { + foreach (var capability in surface.Capabilities.Values.OrderBy(static capability => capability.CapabilityId, StringComparer.Ordinal)) + { + var optionalParameters = capability.Parameters + .Where(static parameter => parameter.IsOptional) + .ToArray(); + + if (optionalParameters.Length == 0 || IsDirectOptionsParameter(optionalParameters, dtoTypeIds)) + { + continue; + } + + var interfaceName = GetUnqualifiedOptionsInterfaceName(capability.CapabilityId); + if (!TypeScriptOptionsInterfaceNaming.RequiresPackageQualifier(interfaceName)) + { + candidates.Add(new OptionsInterfaceCandidate(interfaceName, surface.PackageName, capability.CapabilityId)); + } + } + } + + var collisions = candidates + .GroupBy(static candidate => candidate.InterfaceName, StringComparer.Ordinal) + .Select(static group => new OptionsInterfaceCollision( + group.Key, + group.ToArray(), + group.Select(static candidate => candidate.PackageName).Distinct(StringComparer.Ordinal).ToArray())) + .Where(static collision => collision.PackageNames.Count > 1) + .OrderBy(static collision => collision.InterfaceName, StringComparer.Ordinal) + .ToArray(); + + if (collisions.Length > 0) + { + throw new InvalidOperationException(CreateCollisionMessage(collisions)); + } + } + + private static bool IsDirectOptionsParameter(IReadOnlyList optionalParameters, IReadOnlySet dtoTypeIds) + { + var candidates = optionalParameters + .Where(static parameter => !IsCancellationToken(parameter)) + .ToArray(); + + return candidates.Length == 1 && + string.Equals(candidates[0].Name, "options", StringComparison.Ordinal) && + !string.Equals(candidates[0].TypeId, "callback", StringComparison.Ordinal) && + dtoTypeIds.Contains(candidates[0].TypeId); + } + + private static string GetUnqualifiedOptionsInterfaceName(string capabilityId) + { + var slashIndex = capabilityId.IndexOf('/'); + var methodName = slashIndex < 0 ? capabilityId : capabilityId[(slashIndex + 1)..]; + + return TypeScriptOptionsInterfaceNaming.GetUnqualifiedOptionsInterfaceName(methodName); + } + + private static string CreateCollisionMessage(IReadOnlyList collisions) + { + var builder = new StringBuilder(); + builder.AppendLine("Unqualified TypeScript options interface collision detected."); + + foreach (var collision in collisions) + { + builder.Append("- "); + builder.Append(collision.InterfaceName); + builder.Append(": "); + + var packageSummaries = collision.Candidates + .GroupBy(static candidate => candidate.PackageName, StringComparer.Ordinal) + .OrderBy(static group => group.Key, StringComparer.Ordinal) + .Select(static group => $"'{group.Key}' ({string.Join(", ", group.Select(candidate => candidate.CapabilityId).Order(StringComparer.Ordinal))})") + .ToArray(); + + if (packageSummaries.Length == 2) + { + builder.Append(packageSummaries[0]); + builder.Append(" and "); + builder.Append(packageSummaries[1]); + builder.Append(" both produce this unqualified options interface."); + } + else + { + builder.Append("these packages produce this unqualified options interface: "); + builder.Append(string.Join("; ", packageSummaries)); + builder.Append('.'); + } + + builder.AppendLine(); + } + + builder.Append("Remedy: add the unqualified interface name to "); + builder.Append(nameof(TypeScriptOptionsInterfaceNaming)); + builder.Append('.'); + builder.Append(nameof(TypeScriptOptionsInterfaceNaming.PackageQualifiedOptionsInterfaceNames)); + builder.Append(" so non-core packages use package-qualified options names, then update the TypeScript API compatibility baselines."); + + return builder.ToString(); + } + + private static bool IsCancellationToken(AtsParameter parameter) + => string.Equals(parameter.TypeId, "cancellationToken", StringComparison.Ordinal); + + private sealed record OptionsInterfaceCandidate(string InterfaceName, string PackageName, string CapabilityId); + + private sealed record OptionsInterfaceCollision( + string InterfaceName, + IReadOnlyList Candidates, + IReadOnlyList PackageNames); +} From b3290562466fcf691e9356c32613d89f56e45118 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 15:46:30 -0400 Subject: [PATCH 36/73] Fix TypeScript API export review gaps Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 487b899d-d79d-4349-a84b-a026861bde7f --- src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs | 3 +- .../Commands/Sdk/SdkExportCommand.cs | 2 +- .../TypeScriptApiExportWriter.cs | 5 +- .../Commands/Sdk/SdkExportCommandTests.cs | 8 +-- .../Commands/SdkDumpCommandTests.cs | 29 +++++++++ .../AtsTypeScriptCodeGeneratorTests.cs | 60 +++++++++++++++++++ .../TypeScriptApiCompatTests.cs | 59 +++++++++++++++++- tools/TypeScriptApiCompat/AtsSurface.cs | 2 +- tools/TypeScriptApiCompat/AtsSurfaceParser.cs | 11 +++- .../TypeScriptOptionsCollisionGuard.cs | 10 ++-- 10 files changed, 173 insertions(+), 16 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs index 3a5d3446b22..81cbc7e3e3e 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs @@ -421,7 +421,8 @@ private static string FormatCi(CapabilitiesInfo capabilities) var paramStr = string.Join(", ", c.Parameters.Select(p => { var optional = p.IsOptional ? "?" : ""; - return string.Format(CultureInfo.InvariantCulture, "{0}{1}: {2}", p.Name, optional, p.Type?.TypeId ?? "unknown"); + var nullable = p.IsNullable ? "?" : ""; + return string.Format(CultureInfo.InvariantCulture, "{0}{1}: {2}{3}", p.Name, optional, p.Type?.TypeId ?? "unknown", nullable); })); var returnStr = c.ReturnType?.TypeId ?? "void"; sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0}({1}) -> {2}", c.CapabilityId, paramStr, returnStr)); diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index d6d70617885..c0f9d021391 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -163,7 +163,7 @@ protected override async Task ExecuteAsync(ParseResult parseResul var codeGenPackage = await GetCodeGenerationPackageAsync(language, cancellationToken); if (codeGenPackage is not null) { - integrations.Add(IntegrationReference.FromPackage(codeGenPackage, ExecutionContext.IdentityVersion)); + integrations.Add(IntegrationReference.FromExactPackage(codeGenPackage, ExecutionContext.IdentityVersion)); } return CommandResult.FromExitCode(await ExportApiAsync( diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs index b5e1fe08db5..a2ae70e3e49 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs @@ -127,7 +127,10 @@ private static JsonObject WriteMember(TypeScriptApiMember member) AddIfPresent(json, "summary", member.Summary); AddIfPresent(json, "remarks", member.Remarks); AddIfPresent(json, "examples", member.Examples); - AddIfPresent(json, "deprecated", member.DeprecationMessage); + if (member.DeprecationMessage is not null) + { + json["deprecated"] = member.DeprecationMessage; + } if (member.Parameters.Count > 0) { diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 0af9cc03bfc..c240c3d8c1e 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -532,11 +532,11 @@ public async Task SdkExportForAThirdPartyPackageIsUnaffectedByCheckoutSubstituti /// /// A bare NuGet version is a minimum, not an equality, so a package that is missing from the feed /// restores as the next one up and the export is published under a version it does not describe. - /// Only the requested package is pinned; the code generation package tracks this CLI and is - /// resolved the same way sdk generate resolves it. + /// Both the requested package and the code generation package are part of the exported surface, so + /// both need exact restore ranges. /// [Fact] - public async Task SdkExportPinsOnlyTheRequestedPackageToAnExactVersion() + public async Task SdkExportPinsTheRequestedAndCodeGenerationPackagesToExactVersions() { var interactionService = new TestInteractionService(); using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); @@ -553,7 +553,7 @@ public async Task SdkExportPinsOnlyTheRequestedPackageToAnExactVersion() var codeGeneration = Assert.Single( appHostServerProject.Integrations, integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); - Assert.False(codeGeneration.RequireExactVersion); + Assert.True(codeGeneration.RequireExactVersion); } [Fact] diff --git a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs index 85e4b3b3219..540e1bcb013 100644 --- a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs @@ -334,6 +334,35 @@ public void FormatCi_IncludesExportedValues() Assert.Contains("TestCatalog.Default: test/string = \"你好\"", output); } + [Fact] + public void FormatCi_MarksNullableCapabilityParameters() + { + var capabilities = new CapabilitiesInfo + { + Capabilities = + [ + new CapabilityInfo + { + CapabilityId = "Pkg/withNullable", + Parameters = + [ + new Aspire.Cli.Commands.Sdk.ParameterInfo + { + Name = "name", + IsNullable = true, + Type = new TypeRefInfo { TypeId = "string" } + } + ], + ReturnType = new TypeRefInfo { TypeId = "void" } + } + ] + }; + + var output = InvokeFormatter("FormatCi", capabilities); + + Assert.Contains("Pkg/withNullable(name: string?) -> void", output); + } + [Fact] public void FormatPretty_IncludesExportedValues() { diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 2616537f2c0..d76bd5128d3 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1952,6 +1952,58 @@ await Verify(declarations, extension: "txt") .UseFileName("AtsTypeScriptCodeGeneratorTests.ApiDeclarations"); } + [Fact] + public void ApiExportWritesPlainObsoleteMembersAsDeprecated() + { + var obsoleteAttribute = typeof(PlainObsoleteFixture).GetMethod(nameof(PlainObsoleteFixture.Old))! + .GetCustomAttribute()!; + + var model = new TypeScriptApiModel + { + SchemaVersion = 1, + Language = "typescript", + Package = new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + Modules = + [ + new TypeScriptApiModule + { + Name = "index", + Items = + [ + new TypeScriptApiItem + { + Id = "type:Test", + TypeId = "Test", + Kind = TypeScriptApiItemKind.Interface, + Name = "Test", + Declaration = "export interface Test", + OwningAssemblyName = TestPackageName, + Members = + [ + new TypeScriptApiMember + { + Id = "member:Test.old", + Kind = TypeScriptApiItemKind.Method, + Name = "old", + Declaration = "old(): void", + DeprecationMessage = obsoleteAttribute.Message ?? string.Empty + } + ] + } + ] + } + ], + Declarations = [] + }; + + var exportJson = TypeScriptApiExportWriter.WriteToJson(model, indented: false); + using var document = System.Text.Json.JsonDocument.Parse(exportJson); + var member = document.RootElement.GetProperty("modules")[0].GetProperty("items")[0].GetProperty("members")[0]; + + Assert.True(member.TryGetProperty("deprecated", out var deprecated)); + Assert.Equal(string.Empty, deprecated.GetString()); + } + [Fact] public void ApiExportMethodParametersMatchResolvedPublicSignatures() { @@ -3196,4 +3248,12 @@ private static Dictionary> ParsePublicInterfaceMembers(s return membersByInterface; } + + private sealed class PlainObsoleteFixture + { + [Obsolete] + public void Old() + { + } + } } diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index 5cbd95202a9..af4cef079ed 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -30,7 +30,7 @@ public void ParserReadsAtsCiSurface() Configs.Default: string = "dev" # copied value # Capabilities - Pkg/addThing(name: string, port?: number) -> Pkg/Thing + Pkg/addThing(name: string, port?: number, endpoint: string?) -> Pkg/Thing """); var handle = Assert.Single(surface.HandleTypes.Values); @@ -55,6 +55,11 @@ public void ParserReadsAtsCiSurface() Assert.Equal("Pkg/Thing", capability.ReturnTypeId); Assert.Equal("port", capability.Parameters[1].Name); Assert.True(capability.Parameters[1].IsOptional); + Assert.False(capability.Parameters[1].IsNullable); + Assert.Equal("endpoint", capability.Parameters[2].Name); + Assert.False(capability.Parameters[2].IsOptional); + Assert.True(capability.Parameters[2].IsNullable); + Assert.Equal("string", capability.Parameters[2].TypeId); } [Fact] @@ -377,6 +382,58 @@ public void RunnerFailsWhenUnqualifiedOptionsInterfaceNamesCollide() Assert.Contains("Remedy:", message, StringComparison.Ordinal); } + [Fact] + public void RunnerFailsWhenNullableParametersProduceUnqualifiedOptionsInterfaceCollision() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + WriteSurface(baselineRoot, "Pkg.One", """ + # Capabilities + Pkg.One/withShared(port: number?) -> void + """); + WriteSurface(baselineRoot, "Pkg.Two", """ + # Capabilities + Pkg.Two/withShared(host: string?) -> void + """); + WriteSurface(currentRoot, "Pkg.One", """ + # Capabilities + Pkg.One/withShared(port: number?) -> void + """); + WriteSurface(currentRoot, "Pkg.Two", """ + # Capabilities + Pkg.Two/withShared(host: string?) -> void + """); + + using var error = new StringWriter(); + var originalError = Console.Error; + try + { + Console.SetError(error); + + var exitCode = TypeScriptApiCompatRunner.Run(new CommandLineOptions( + baselineRoot, + currentRoot, + workspace.Path, + BaselineSuppressionsRoot: null, + ExcludedPackagesFile: null, + ReportPath: null, + GitHubAnnotations: false)); + + Assert.Equal(2, exitCode); + } + finally + { + Console.SetError(originalError); + } + + var message = error.ToString(); + Assert.Contains("WithSharedOptions", message, StringComparison.Ordinal); + Assert.Contains("'Pkg.One'", message, StringComparison.Ordinal); + Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); + } + private static void WriteSurface(string rootPath, string packageName, string content) { var apiDirectory = Path.Combine(rootPath, "src", packageName, "api"); diff --git a/tools/TypeScriptApiCompat/AtsSurface.cs b/tools/TypeScriptApiCompat/AtsSurface.cs index 632b20dce13..65cdf042b1e 100644 --- a/tools/TypeScriptApiCompat/AtsSurface.cs +++ b/tools/TypeScriptApiCompat/AtsSurface.cs @@ -23,7 +23,7 @@ internal sealed record AtsExportedValue(string Path, string TypeId, string Value internal sealed record AtsCapability(string CapabilityId, IReadOnlyList Parameters, string ReturnTypeId); -internal sealed record AtsParameter(string Name, string TypeId, bool IsOptional); +internal sealed record AtsParameter(string Name, string TypeId, bool IsOptional, bool IsNullable); internal sealed class AtsSurfaceSet { diff --git a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs index 9f04fbfb0bf..7e4640db9e1 100644 --- a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs +++ b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs @@ -218,12 +218,19 @@ private static AtsParameter ParseParameter(string parameterText) throw new InvalidDataException($"Invalid parameter '{parameterText}'."); } + // Capability parameters are emitted as: + // name?: type? // optional nullable parameter + // options: Pkg/Options? // required parameter whose nullability still generates an options bag + // Optionality lives on the parameter name, and nullability lives on the type token so the + // compat guard can mirror the TypeScript projector's `IsOptional || IsNullable` rule. var nameText = parameterText[..separatorIndex]; var isOptional = nameText.EndsWith('?'); var name = isOptional ? nameText[..^1] : nameText; - var typeId = parameterText[(separatorIndex + 2)..]; + var typeText = parameterText[(separatorIndex + 2)..]; + var isNullable = typeText.EndsWith('?'); + var typeId = isNullable ? typeText[..^1] : typeText; - return new AtsParameter(name, typeId, isOptional); + return new AtsParameter(name, typeId, isOptional, isNullable); } private static string StripDescription(string value) diff --git a/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs b/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs index ddc7bbdf505..d6a42255b26 100644 --- a/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs +++ b/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs @@ -19,11 +19,11 @@ public static void Validate(AtsSurfaceSet surfaceSet) { foreach (var capability in surface.Capabilities.Values.OrderBy(static capability => capability.CapabilityId, StringComparer.Ordinal)) { - var optionalParameters = capability.Parameters - .Where(static parameter => parameter.IsOptional) + var optionsParameters = capability.Parameters + .Where(static parameter => parameter.IsOptional || parameter.IsNullable) .ToArray(); - if (optionalParameters.Length == 0 || IsDirectOptionsParameter(optionalParameters, dtoTypeIds)) + if (optionsParameters.Length == 0 || IsDirectOptionsParameter(optionsParameters, dtoTypeIds)) { continue; } @@ -52,9 +52,9 @@ public static void Validate(AtsSurfaceSet surfaceSet) } } - private static bool IsDirectOptionsParameter(IReadOnlyList optionalParameters, IReadOnlySet dtoTypeIds) + private static bool IsDirectOptionsParameter(IReadOnlyList optionsParameters, IReadOnlySet dtoTypeIds) { - var candidates = optionalParameters + var candidates = optionsParameters .Where(static parameter => !IsCancellationToken(parameter)) .ToArray(); From f27bf0d94df8aac2c7d13032166d55c39e4cb625 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 16:34:09 -0400 Subject: [PATCH 37/73] Tighten TypeScript API export versioning Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkExportCommand.cs | 19 +++++----- .../TypeScriptApiProjector.cs | 11 +++--- .../TypeScriptOptionsInterfaceNaming.cs | 27 +++++++++++-- .../Commands/Sdk/SdkExportCommandTests.cs | 38 ++++++++++++++++--- .../AtsTypeScriptCodeGeneratorTests.cs | 8 ++++ 5 files changed, 79 insertions(+), 24 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index c0f9d021391..c004f5d3fb5 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -129,25 +129,20 @@ protected override async Task ExecuteAsync(ParseResult parseResul var isCorePackage = string.Equals(reference.Name, CorePackageName, StringComparison.OrdinalIgnoreCase); packageName = isCorePackage ? CorePackageName : reference.Name; - // The core package is always restored by the scanner AppHost, so adding it again would - // produce a duplicate package reference. - if (isCorePackage) + if (IsFirstPartyHostingPackage(packageName)) { - // The scanner loads the core assemblies this CLI was built against, so a different - // requested version would be exported as this CLI's surface under someone else's - // version number. That is the same stale-signature problem this command exists to - // fix, so refuse instead of labelling the export with a version it does not describe. var requested = StripBuildMetadata(packageVersion); if (!string.Equals(requested, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) { return CommandResult.Failure( CliExitCodes.InvalidCommand, - $"This CLI can only export {CorePackageName}@{ExecutionContext.IdentitySdkVersion}, but {packageVersion} was requested. " + - $"The scanner loads the core assemblies this CLI ships with, so exporting a different version would describe the wrong API surface. " + + $"This CLI can only export first-party Aspire packages at {ExecutionContext.IdentitySdkVersion}, but {packageName}@{packageVersion} was requested. " + + $"The TypeScript generator is restored at this CLI's version, so exporting a different package version would describe a mixed SDK surface. " + $"Run the export with the {requested} CLI instead."); } } - else + + if (!isCorePackage) { // Pin the requested version: a bare NuGet version is a minimum, so an unavailable // version would restore as a later one and be published under the wrong number. @@ -215,6 +210,10 @@ private static string StripBuildMetadata(string version) return plusIndex < 0 ? version : version[..plusIndex]; } + private static bool IsFirstPartyHostingPackage(string packageName) + => string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase) || + packageName.StartsWith($"{CorePackageName}.", StringComparison.OrdinalIgnoreCase); + /// /// Refuses an export the scanner would satisfy from a local checkout instead of restoring the /// requested package version. diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index e131ccc351f..880bdf820ce 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -1662,10 +1662,11 @@ internal static string ToPascalCase(string name) /// /// /// - /// Names stay unqualified unless the checked-in shipped ATS surface already has a real - /// cross-package collision for that unqualified name. That preserves the old public names for - /// the unique option bags while still making the known collision groups a function of the - /// capability alone. + /// First-party Aspire names stay unqualified unless the checked-in shipped ATS surface already + /// has a real cross-package collision for that unqualified name. That preserves the old public + /// names for the unique option bags while still making the known collision groups a function of + /// the capability alone. Third-party assemblies are always qualified because their package + /// exports are produced one at a time and cannot rely on this repository's collision guard. /// /// /// The core hosting package keeps unqualified names even inside a collision group. Other @@ -1681,7 +1682,7 @@ internal static string GetOptionsInterfaceName(string methodName, string owningA var unqualifiedName = TypeScriptOptionsInterfaceNaming.GetUnqualifiedOptionsInterfaceName(methodName); if (string.IsNullOrEmpty(owningAssemblyName) || string.Equals(owningAssemblyName, AtsConstants.AspireHostingAssembly, StringComparison.Ordinal) || - !TypeScriptOptionsInterfaceNaming.RequiresPackageQualifier(unqualifiedName)) + !TypeScriptOptionsInterfaceNaming.RequiresPackageQualifier(unqualifiedName, owningAssemblyName)) { return unqualifiedName; } diff --git a/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs b/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs index b339cf871ca..3ef0e5c2f6c 100644 --- a/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs +++ b/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs @@ -5,9 +5,14 @@ namespace Aspire.Shared.CodeGeneration; internal static class TypeScriptOptionsInterfaceNaming { - // These are the duplicate unqualified names in the checked-in shipped ATS surface. Keep unique - // names unqualified for compatibility; when the TypeScript API compatibility guard finds a new - // duplicate, add that name here so non-core packages move to package-qualified names together. + private const string AspireHostingAssembly = "Aspire.Hosting"; + private const string AspireHostingAssemblyPrefix = "Aspire.Hosting."; + + // These are the duplicate unqualified names in the checked-in shipped ATS surface. First-party + // packages keep unique names unqualified for compatibility; when the TypeScript API + // compatibility guard finds a new duplicate, add that name here so non-core Aspire packages + // move to package-qualified names together. Third-party packages are always qualified because + // the repository guard cannot see their collisions before users concatenate package exports. internal static IReadOnlySet PackageQualifiedOptionsInterfaceNames { get; } = new HashSet(StringComparer.Ordinal) { @@ -30,6 +35,22 @@ internal static class TypeScriptOptionsInterfaceNaming internal static bool RequiresPackageQualifier(string unqualifiedInterfaceName) => PackageQualifiedOptionsInterfaceNames.Contains(unqualifiedInterfaceName); + internal static bool RequiresPackageQualifier(string unqualifiedInterfaceName, string owningAssemblyName) + { + if (string.IsNullOrEmpty(owningAssemblyName) || + string.Equals(owningAssemblyName, AspireHostingAssembly, StringComparison.Ordinal)) + { + return false; + } + + if (!owningAssemblyName.StartsWith(AspireHostingAssemblyPrefix, StringComparison.Ordinal)) + { + return true; + } + + return RequiresPackageQualifier(unqualifiedInterfaceName); + } + internal static string GetUnqualifiedOptionsInterfaceName(string methodName) { var simpleName = methodName.Contains('.') diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index c240c3d8c1e..dbbba42a280 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -45,11 +45,12 @@ public async Task SdkExportForExactPackageWritesCanonicalDocumentToStdout() var interactionService = new TestInteractionService(); using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); using var _ = workspace; + var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion}"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("typescript", "Aspire.Hosting.Redis", "13.5.0"), rpcClient.LastExportRequest); + Assert.Equal(("typescript", "Aspire.Hosting.Redis", packageVersion), rpcClient.LastExportRequest); var stdout = Assert.Single(interactionService.DisplayedRawText, entry => entry.ConsoleOverride == ConsoleOutput.Standard); using var document = JsonDocument.Parse(stdout.Text); @@ -80,8 +81,9 @@ public async Task SdkExportSendsProgressToStderrOnly() var interactionService = new TestInteractionService(); using var provider = CreateProvider(interactionService, out var workspace, out _); using var _2 = workspace; + var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0 --output " + Path.Combine(workspace.WorkspaceRoot.FullName, "api.json")); + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion} --output " + Path.Combine(workspace.WorkspaceRoot.FullName, "api.json")); Assert.Equal(CliExitCodes.Success, exitCode); @@ -104,8 +106,9 @@ public async Task SdkExportPassesPackageSourceThroughToPrepare() using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); + var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0 --source /tmp/aspire-hive"); + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion} --source /tmp/aspire-hive"); Assert.Equal(CliExitCodes.Success, exitCode); Assert.Equal("/tmp/aspire-hive", appHostServerProject.PackageSourceOverride); @@ -123,8 +126,9 @@ public async Task SdkExportAddsTheCodeGenerationPackageForTheRequestedLanguage() using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); + var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion}"); Assert.Equal(CliExitCodes.Success, exitCode); Assert.Contains( @@ -248,6 +252,27 @@ public async Task SdkExportForASubstitutedPackageAtTheCheckoutVersionSucceeds() Assert.Equal(("typescript", "Aspire.Hosting.Redis", checkoutVersion), rpcClient.LastExportRequest); } + [Fact] + public async Task SdkExportRejectsFirstPartyPackageVersionSkewEvenWithoutCheckoutSubstitution() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.5.0"); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.4.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + /// /// The version this CLI reports is overrideable (ASPIRE_CLI_VERSION, the install sidecar), /// so comparing the request against it alone lets a caller name the checkout whatever they like. @@ -542,8 +567,9 @@ public async Task SdkExportPinsTheRequestedAndCodeGenerationPackagesToExactVersi using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); + var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion}"); Assert.Equal(CliExitCodes.Success, exitCode); diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index d76bd5128d3..4dbb105cb03 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2733,6 +2733,14 @@ public void UniqueOptionsInterfaceNamesStayUnqualified() Assert.Equal("WithUniqueSettingOptions", name); } + [Fact] + public void ThirdPartyOptionsInterfaceNamesAreQualifiedEvenWhenTheNameIsUniqueInThisRepository() + { + var name = TypeScriptApiProjector.GetOptionsInterfaceName("withDescription", "Contoso.Aspire.Hosting.Widgets"); + + Assert.Equal("Contoso_x002E_Aspire_x002E_Hosting_x002E_WidgetsWithDescriptionOptions", name); + } + /// /// An options interface is documented by, and keyed to, the assembly whose capability produced /// it rather than the package the export was requested for. From 7b1a3af4c92d119e35c62784ef92e27ff1760b0c Mon Sep 17 00:00:00 2001 From: adamint Date: Sun, 9 Aug 2026 16:57:01 -0400 Subject: [PATCH 38/73] Validate the substituted code generator against the CLI identity Repository mode substitutes every Aspire.Hosting* reference with the matching project under src/, including the code generation package, which is added pinned to this CLI's identity version. The pin is discarded by the substitution, and for a third-party integration the request-level guard finds no substitution for the requested name and returns clean -- so a checkout on a different version line published generator output this CLI never produced under the requested package version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 487b899d-d79d-4349-a84b-a026861bde7f --- .../Commands/Sdk/SdkExportCommand.cs | 58 ++++++++++++++++++- .../Commands/Sdk/SdkExportCommandTests.cs | 45 ++++++++++++++ 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index c004f5d3fb5..ed44a72d93c 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -166,6 +166,7 @@ protected override async Task ExecuteAsync(ParseResult parseResul packageName, packageVersion, integrations, + codeGenPackage, packageSource, outputFile, cancellationToken)); @@ -257,8 +258,9 @@ private static bool IsFirstPartyHostingPackage(string packageName) /// The scanner AppHost that will restore the export. /// The package being exported. /// The version the caller asked for. + /// The code generation package the export will load, when one was resolved. /// The rejection reason, or when the request is exportable. - private string? ValidateRequestedPackageIsRestorable(IAppHostServerProject serverProject, string packageName, string packageVersion) + private string? ValidateRequestedPackageIsRestorable(IAppHostServerProject serverProject, string packageName, string packageVersion, string? codeGenPackage) { var isCorePackage = string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase); @@ -283,7 +285,7 @@ private static bool IsFirstPartyHostingPackage(string packageName) // src/Aspire.Hosting. if (serverProject.GetLocalProjectSubstitution(packageName) is not { } substitution) { - return null; + return ValidateCodeGenerationPackageIsRestorable(serverProject, codeGenPackage); } var preamble = $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {substitution.ProjectPath} " + @@ -328,6 +330,55 @@ private static bool IsFirstPartyHostingPackage(string packageName) $"Run the export with the {requested} CLI, or request {packageName}@{ExecutionContext.IdentitySdkVersion}."; } + return ValidateCodeGenerationPackageIsRestorable(serverProject, codeGenPackage); + } + + /// + /// Rejects an export whose code generator would be built from a checkout that does not match this + /// CLI, or when the generator is exportable. + /// + /// + /// The generator reference is pinned to when it is + /// added, but repository mode substitutes every Aspire.Hosting* reference with the + /// matching project under src/ and that substitution ignores the pin. The exported document + /// is labelled with the requested package version and records the generator's output shape, so a + /// checkout on a different version line silently publishes generator output this CLI never + /// produced. The request-level checks above cannot catch it: for a third-party integration they + /// return before looking at anything, because nothing under src/ carries that name. + /// + private string? ValidateCodeGenerationPackageIsRestorable(IAppHostServerProject serverProject, string? codeGenPackage) + { + if (codeGenPackage is null || serverProject.GetLocalProjectSubstitution(codeGenPackage) is not { } substitution) + { + return null; + } + + var preamble = $"This CLI runs from an Aspire repository checkout, so the {codeGenPackage} code generator is built from " + + $"{substitution.ProjectPath} instead of being restored at this CLI's version."; + + if (ExecutionContext.IdentityVersionForged) + { + return $"{preamble} This run also claims a version through ASPIRE_CLI_VERSION, so nothing can confirm the " + + $"checkout really is {ExecutionContext.IdentityVersion}. Re-run without the override, or export from an installed CLI."; + } + + if (substitution.CheckoutVersionPrefix is not string checkoutPrefix) + { + return $"{preamble} This checkout does not say which version it builds (eng/Versions.props is missing or unreadable), " + + $"so the generated document cannot be attributed to a known generator. Export from an installed CLI instead."; + } + + // Compare on Major.Minor.Patch only. CheckoutVersionPrefix is that shape by construction while + // the identity carries whatever prerelease label this build was stamped with, so comparing the + // strings rejected the ordinary local development case where the checkout is exactly this CLI. + if (!SemVersion.TryParse(ExecutionContext.IdentitySdkVersion, SemVersionStyles.Any, out var identityVersion) + || $"{identityVersion.Major}.{identityVersion.Minor}.{identityVersion.Patch}" != checkoutPrefix) + { + return $"{preamble} That checkout builds {checkoutPrefix}, but this CLI is {ExecutionContext.IdentitySdkVersion}, so the " + + $"export would describe the checkout's generator output as this CLI's. " + + $"Export from a {checkoutPrefix} CLI, or point this one at a {ExecutionContext.IdentitySdkVersion} checkout."; + } + return null; } @@ -336,6 +387,7 @@ private async Task ExportApiAsync( string packageName, string packageVersion, List integrations, + string? codeGenPackage, string? packageSource, FileInfo? outputFile, CancellationToken cancellationToken) @@ -357,7 +409,7 @@ private async Task ExportApiAsync( sdkVersion, integrations, packageSource, - validateProject: serverProject => rejection = ValidateRequestedPackageIsRestorable(serverProject, packageName, packageVersion), + validateProject: serverProject => rejection = ValidateRequestedPackageIsRestorable(serverProject, packageName, packageVersion, codeGenPackage), cancellationToken); if (session is null) diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index dbbba42a280..fc8d968c869 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -252,6 +252,51 @@ public async Task SdkExportForASubstitutedPackageAtTheCheckoutVersionSucceeds() Assert.Equal(("typescript", "Aspire.Hosting.Redis", checkoutVersion), rpcClient.LastExportRequest); } + [Fact] + public async Task SdkExportRejectsWhenTheCheckoutWouldSubstituteAGeneratorFromADifferentVersionLine() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + appHostServerProject, + identityVersion: "13.5.0"); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.CodeGeneration.TypeScript", "13.4.0"); + + // The generator is a first-party Aspire.Hosting* reference, so repository mode builds it from + // src/ and discards the version it was pinned to. A third-party package name matches nothing + // under src/, so the request-level guard finds no substitution and returns clean — yet the + // document this run would publish carries the requested version while describing the shape a + // 13.4.0 generator emits. + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + Assert.Empty(interactionService.DisplayedRawText); + } + + [Fact] + public async Task SdkExportAllowsASubstitutedGeneratorAtTheCheckoutVersion() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.CodeGeneration.TypeScript", CheckoutVersionPrefix(provider)); + + // A checkout on this CLI's own version line is the local development case: the generator built + // from src/ is the generator this CLI would have restored, so the export stays supported. + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("typescript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); + } + [Fact] public async Task SdkExportRejectsFirstPartyPackageVersionSkewEvenWithoutCheckoutSubstitution() { From e279ec3018a4afc59b17219b4d07ea3dc8b94518 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 17:51:00 -0400 Subject: [PATCH 39/73] Address review findings on the canonical TypeScript API export Keep the code generator loadable when the shared contract predates the exporter. Aspire.TypeSystem is force-shared from the apphost server's default load context and freezes its AssemblyVersion, so a CLI that predates IApiReferenceExporter still binds a newer SDK's codegen assembly - it just has no such interface in its bundled copy. A type's interface list resolves eagerly at load, so implementing the interface on AtsTypeScriptCodeGenerator made the generator itself unloadable there and took TypeScript generation down with export. Export now lives on its own type and CodeGeneratorResolver discovers exporters independently, still gated on a generator existing for the language. Declare AspireClientRpc in the runtime declaration fragment. Every exported entry point is a free function taking the client explicitly, so an Aspire.Hosting export naming that type was the one declaration set that did not type-check standalone. Normalize the requested package version before it reaches the export. SemVer build metadata is not part of NuGet package identity, so Contoso@2.0.0+fake restores what 2.0.0 does; recording the requested string published the surface under a version no feed can serve. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkExportCommand.cs | 19 ++- .../AtsTypeScriptApiReferenceExporter.cs | 58 ++++++++ .../AtsTypeScriptCodeGenerator.cs | 23 +-- .../TypeScriptApiProjector.cs | 8 +- .../CodeGeneration/CodeGenerationService.cs | 7 +- .../CodeGeneration/CodeGeneratorResolver.cs | 140 +++++++++++++----- .../Commands/Sdk/SdkExportCommandTests.cs | 43 +++++- .../AtsTypeScriptCodeGeneratorTests.cs | 29 ++++ ...eneratorTests.ApiDeclarations.verified.txt | 3 +- ...CodeGeneratorTests.ApiExport.verified.json | 2 +- .../CodeGeneration/ApiReferenceExportTests.cs | 2 +- .../CodeGenerationResolverTests.cs | 47 +++++- 12 files changed, 308 insertions(+), 73 deletions(-) create mode 100644 src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index ed44a72d93c..7370a87df7e 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -115,7 +115,13 @@ protected override async Task ExecuteAsync(ParseResult parseResul $"Invalid package '{package}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@13.5.0); project references are not supported by sdk export."); } - packageVersion = reference.Version; + // SemVer build metadata is not part of NuGet package identity + // (https://semver.org/#spec-item-10), so `Contoso@2.0.0+fake` restores exactly the + // package `Contoso@2.0.0` does. Recording the requested string verbatim would publish + // that package's surface under a version no feed can serve, which is precisely the + // exact-version guarantee this command exists to make. Normalizing once here keeps the + // first-party guard, the restore pin, and the exported label naming the same version. + packageVersion = StripBuildMetadata(reference.Version); // NuGet package ids are case-insensitive, so `aspire.hosting` names the core package // exactly as `Aspire.Hosting` does: @@ -131,14 +137,13 @@ protected override async Task ExecuteAsync(ParseResult parseResul if (IsFirstPartyHostingPackage(packageName)) { - var requested = StripBuildMetadata(packageVersion); - if (!string.Equals(requested, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(packageVersion, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) { return CommandResult.Failure( CliExitCodes.InvalidCommand, $"This CLI can only export first-party Aspire packages at {ExecutionContext.IdentitySdkVersion}, but {packageName}@{packageVersion} was requested. " + $"The TypeScript generator is restored at this CLI's version, so exporting a different package version would describe a mixed SDK surface. " + - $"Run the export with the {requested} CLI instead."); + $"Run the export with the {packageVersion} CLI instead."); } } @@ -146,9 +151,9 @@ protected override async Task ExecuteAsync(ParseResult parseResul { // Pin the requested version: a bare NuGet version is a minimum, so an unavailable // version would restore as a later one and be published under the wrong number. - // Use packageName rather than reference.Name so the restored reference and the - // exported label can never name the package differently. - integrations.Add(IntegrationReference.FromExactPackage(packageName, reference.Version)); + // Use packageName/packageVersion rather than the raw reference so the restored + // reference and the exported label can never name a different package or version. + integrations.Add(IntegrationReference.FromExactPackage(packageName, packageVersion)); } } diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs new file mode 100644 index 00000000000..d604b091873 --- /dev/null +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text.Json; +using Aspire.TypeSystem; + +namespace Aspire.Hosting.CodeGeneration.TypeScript; + +/// +/// Exports the canonical TypeScript API reference for the surface +/// generates. +/// +/// +/// +/// This deliberately lives on its own type rather than on . +/// Aspire.TypeSystem is force-shared from the apphost server's default +/// (see +/// src/Aspire.Hosting.RemoteHost/IntegrationLoadContext.cs) and freezes its strong-name +/// AssemblyVersion at a constant so an older CLI still binds a newer SDK's codegen assembly. +/// Version binding therefore succeeds, but an older CLI's bundled copy has no +/// in it: the interface is new. A type's interface list is +/// resolved eagerly when the type loads, so putting the interface on the code generator would make +/// the generator itself unloadable under any CLI that predates the interface, and +/// CodeGeneratorResolver would then find no TypeScript generator at all — TypeScript +/// generation, not just export, would stop working. +/// +/// +/// Keeping export on a separate type confines that loss to the feature the older CLI cannot use +/// anyway: CodeGeneratorResolver salvages the loadable types out of the +/// , so the generator survives and only +/// this type disappears. +/// +/// +internal sealed class AtsTypeScriptApiReferenceExporter : IApiReferenceExporter +{ + /// + public string Language => "TypeScript"; + + /// + public JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options) + { + ArgumentNullException.ThrowIfNull(context); + ArgumentNullException.ThrowIfNull(options); + + // Build the projector from the same context the generator would use, so the exported + // documentation describes the exact signatures generation would emit rather than a + // second, independently derived reading of the ATS context. + var projector = new TypeScriptApiProjector(context); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(options.PackageName, options.PackageVersion), + options.ExportingAssemblyNames); + + // JsonDocument.Parse + Clone rather than JsonSerializer, because this assembly is + // AOT-compatible and the serializer's reflection-based overloads are not. + using var document = JsonDocument.Parse(TypeScriptApiExportWriter.WriteToJson(model)); + return document.RootElement.Clone(); + } +} diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index 8e04c4f871e..2d8e92e6188 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.Text; -using System.Text.Json; using System.Text.Json.Nodes; using Aspire.Shared.Json; using Aspire.TypeSystem; @@ -106,7 +105,7 @@ internal sealed class ExportedValueTreeNode /// /// /// -internal sealed class AtsTypeScriptCodeGenerator : ICodeGenerator, IApiReferenceExporter +internal sealed class AtsTypeScriptCodeGenerator : ICodeGenerator { private TextWriter _writer = null!; @@ -444,26 +443,6 @@ public Dictionary GenerateDistributedApplication(AtsContext cont return files; } - /// - public JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options) - { - ArgumentNullException.ThrowIfNull(context); - ArgumentNullException.ThrowIfNull(options); - - // Build the projector from the same context the generator would use, so the exported - // documentation describes the exact signatures generation would emit rather than a - // second, independently derived reading of the ATS context. - var projector = new TypeScriptApiProjector(context); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(options.PackageName, options.PackageVersion), - options.ExportingAssemblyNames); - - // JsonDocument.Parse + Clone rather than JsonSerializer, because this assembly is - // AOT-compatible and the serializer's reflection-based overloads are not. - using var document = JsonDocument.Parse(TypeScriptApiExportWriter.WriteToJson(model)); - return document.RootElement.Clone(); - } - /// /// Generates the aspire.mts SDK file with capability-based API. /// diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 880bdf820ce..7fe13af7ff2 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -46,7 +46,12 @@ internal sealed partial class TypeScriptApiProjector { "Awaitable", "MarshalledHandle", "Handle", "HandleReference", "AbortSignal", "CancellationToken", "ReferenceExpression", "AspireList", "AspireDict", "ResourceBuilderBase", "InputType", - "InteractionInput", "InteractionInputCollection", "InteractionInputCollectionPromise" + "InteractionInput", "InteractionInputCollection", "InteractionInputCollectionPromise", + // Every exported entry point is a free function that takes the client explicitly + // (see EntryPointClientParameterType), so a package contributing an entry point names this + // symbol in a signature. Without it here the fragment would be the only self-contained + // declaration set that does not compile on its own. + "AspireClientRpc" }; private const string RuntimeDeclarationContent = """ @@ -64,6 +69,7 @@ export interface ResourceBuilderBase extends HandleReference {} export interface InteractionInput { readonly name: string; } export interface InteractionInputCollection extends HandleReference {} export interface InteractionInputCollectionPromise extends PromiseLike {} + export interface AspireClientRpc { readonly connected: boolean; invokeCapability(capabilityId: string, args?: Record): Promise; } """; private readonly TypeScriptResolvedModel _resolved; diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index 6516cd7541e..a225aea9eab 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -303,10 +303,13 @@ public JsonElement ExportApi(string language, string packageName, string package throw new ArgumentException(BuildNoCodeGeneratorMessage(language)); } - if (generator is not IApiReferenceExporter exporter) + // Resolved through the resolver rather than cast off the generator: the exporter is + // discovered as its own type so that adding the interface never changes the generator + // type's eagerly resolved interface list. See AtsTypeScriptApiReferenceExporter. + if (_resolver.GetApiReferenceExporter(language) is not { } exporter) { throw new NotSupportedException( - $"The '{generator.Language}' code generator does not implement {nameof(IApiReferenceExporter)}, " + + $"The '{generator.Language}' language provides no {nameof(IApiReferenceExporter)}, " + "so it cannot produce an API reference export. " + $"Supported languages for API export: {BuildApiExportLanguageList()}."); } diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs index d5baa4a9a27..081167dd695 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGeneratorResolver.cs @@ -14,6 +14,7 @@ namespace Aspire.Hosting.RemoteHost.CodeGeneration; internal sealed class CodeGeneratorResolver { private readonly Lazy> _generators; + private readonly Lazy> _exporters; private readonly ILogger _logger; public CodeGeneratorResolver( @@ -34,6 +35,8 @@ internal CodeGeneratorResolver( _logger = logger; _generators = new Lazy>( () => DiscoverGenerators(serviceProvider, assembliesProvider())); + _exporters = new Lazy>( + () => DiscoverExporters(serviceProvider, assembliesProvider())); } /// @@ -48,21 +51,43 @@ internal CodeGeneratorResolver( } /// - /// Gets the API reference exporter for the specified language, if the language's code generator - /// also supports API export. + /// Gets the API reference exporter for the specified language, if the language supports API export. /// /// The target language (e.g., "TypeScript", "Python"). /// /// The exporter, or when no generator is registered for the language or - /// the registered generator does not implement . + /// the language provides no . /// /// - /// This resolves through rather than discovering exporters - /// separately, so an exporter can never be reachable for a language whose code generator is not. - /// A documented API that no generator produces would be worse than no documentation at all. + /// + /// An exporter is never reachable for a language whose code generator is not: a documented API + /// that no generator produces would be worse than no documentation at all. That is why the + /// generator lookup gates the result even though exporters are discovered independently. + /// + /// + /// Exporters are discovered as their own types rather than read off the generator so that a + /// language provider can add export support without changing the generator type's interface + /// list. Aspire.TypeSystem is force-shared from the default load context, so a generator + /// implementing a newly added shared interface fails to load entirely under a CLI that predates + /// it (see AtsTypeScriptApiReferenceExporter). A generator that implements the interface + /// itself is still honored, so a provider that keeps both roles on one type keeps working. + /// /// public IApiReferenceExporter? GetApiReferenceExporter(string language) - => GetCodeGenerator(language) as IApiReferenceExporter; + { + if (GetCodeGenerator(language) is not { } generator) + { + return null; + } + + if (generator is IApiReferenceExporter selfExporter) + { + return selfExporter; + } + + _exporters.Value.TryGetValue(language, out var exporter); + return exporter; + } /// /// Gets the languages of all discovered code generators. @@ -81,35 +106,8 @@ private Dictionary DiscoverGenerators( foreach (var assembly in assemblies) { - Type[] types; var assemblyName = assembly.GetName().Name; - var hadTypeLoadFailure = false; - try - { - types = assembly.GetTypes(); - } - catch (ReflectionTypeLoadException ex) - { - hadTypeLoadFailure = true; - // Surface loader binding failures at Warning level. These typically indicate - // a binary mismatch between the bundled runtime assemblies and the integration - // assemblies loaded from disk (for example, when Aspire.TypeSystem versions - // diverge). Including the LoaderExceptions in the log is essential for - // diagnosing these failures, which previously disappeared into Debug-level - // output that the apphost server never wrote to disk. - var loaderMessages = ex.LoaderExceptions is { Length: > 0 } loaders - ? string.Join("; ", loaders.Where(e => e is not null).Select(e => e!.Message).Distinct()) - : "(no LoaderExceptions captured)"; - _logger.LogWarning( - ex, - "Some types in assembly '{AssemblyName}' could not be loaded; {LoadedCount} of {TotalCount} types are available. LoaderExceptions: {LoaderExceptions}", - assemblyName, - ex.Types.Count(t => t is not null), - ex.Types.Length, - loaderMessages); - // Use the types that were successfully loaded - types = ex.Types.Where(t => t is not null).ToArray()!; - } + var types = GetLoadableTypes(assembly, assemblyName, out var hadTypeLoadFailure); var discoveredInAssembly = 0; foreach (var type in types) @@ -150,6 +148,78 @@ private Dictionary DiscoverGenerators( return generators; } + private Dictionary DiscoverExporters( + IServiceProvider serviceProvider, + IReadOnlyList assemblies) + { + var exporters = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var assembly in assemblies) + { + var assemblyName = assembly.GetName().Name; + + // An assembly with no exporter is the normal case (most languages generate code they + // cannot yet describe), so unlike generator discovery this pass never warns about + // finding nothing. A type-load failure was already reported by DiscoverGenerators. + foreach (var type in GetLoadableTypes(assembly, assemblyName, out _)) + { + if (type.IsAbstract || type.IsInterface || !typeof(IApiReferenceExporter).IsAssignableFrom(type)) + { + continue; + } + + try + { + var exporter = (IApiReferenceExporter)ActivatorUtilities.CreateInstance(serviceProvider, type); + exporters[exporter.Language] = exporter; + _logger.LogDebug("Discovered API reference exporter: {TypeName} for language '{Language}'", type.Name, exporter.Language); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Failed to instantiate API reference exporter '{TypeName}'", type.Name); + } + } + } + + return exporters; + } + + /// + /// Returns the types an assembly can actually load, keeping the ones that bound when others did + /// not. Dropping the whole assembly on a single unloadable type would take every generator in it + /// down with that type. + /// + private Type[] GetLoadableTypes(Assembly assembly, string? assemblyName, out bool hadTypeLoadFailure) + { + hadTypeLoadFailure = false; + + try + { + return assembly.GetTypes(); + } + catch (ReflectionTypeLoadException ex) + { + hadTypeLoadFailure = true; + // Surface loader binding failures at Warning level. These typically indicate + // a binary mismatch between the bundled runtime assemblies and the integration + // assemblies loaded from disk (for example, when Aspire.TypeSystem versions + // diverge). Including the LoaderExceptions in the log is essential for + // diagnosing these failures, which previously disappeared into Debug-level + // output that the apphost server never wrote to disk. + var loaderMessages = ex.LoaderExceptions is { Length: > 0 } loaders + ? string.Join("; ", loaders.Where(e => e is not null).Select(e => e!.Message).Distinct()) + : "(no LoaderExceptions captured)"; + _logger.LogWarning( + ex, + "Some types in assembly '{AssemblyName}' could not be loaded; {LoadedCount} of {TotalCount} types are available. LoaderExceptions: {LoaderExceptions}", + assemblyName, + ex.Types.Count(t => t is not null), + ex.Types.Length, + loaderMessages); + return ex.Types.Where(t => t is not null).ToArray()!; + } + } + private static bool LooksLikeCodeGeneratorAssembly(string? assemblyName) => assemblyName is not null && assemblyName.StartsWith("Aspire.Hosting.CodeGeneration.", StringComparison.OrdinalIgnoreCase); diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index fc8d968c869..714f682a339 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -174,8 +174,13 @@ public async Task SdkExportWithMismatchedCoreVersionReturnsInvalidCommand() public async Task SdkExportAcceptsCoreVersionThatDiffersOnlyByBuildMetadata() { var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out _); - using var _2 = workspace; + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName)); var executionContext = provider.GetRequiredService(); @@ -184,6 +189,40 @@ public async Task SdkExportAcceptsCoreVersionThatDiffersOnlyByBuildMetadata() $"sdk export --language typescript --package Aspire.Hosting@{executionContext.IdentitySdkVersion}+build.5"); Assert.Equal(0, exitCode); + + // The metadata is accepted but must not survive into the document: see + // SdkExportPublishesTheVersionNuGetResolvesRatherThanTheRequestedBuildMetadata. + Assert.Equal( + ("typescript", "Aspire.Hosting", executionContext.IdentitySdkVersion), + rpcClient.LastExportRequest); + } + + /// + /// SemVer build metadata is not part of NuGet package identity, so 2.0.0+fake restores the + /// same package 2.0.0 does. Publishing the surface under the requested string would label + /// the document with a version no feed can serve, which is exactly the exact-version guarantee + /// this command exists to make. The restore pin has to agree for the same reason. + /// + [Fact] + public async Task SdkExportPublishesTheVersionNuGetResolvesRatherThanTheRequestedBuildMetadata() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0+fake"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("typescript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); + + var requested = Assert.Single( + appHostServerProject.Integrations, + integration => integration.Name == "Contoso.Aspire.Widgets"); + Assert.Equal("2.0.0", requested.Version); } [Theory] diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 4dbb105cb03..d87375f23b4 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2184,6 +2184,35 @@ public void ApiExportDeclarationFragmentsReferenceOnlyDeclaredOrBuiltInSymbols() new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), [TestPackageName]); + AssertDeclarationFragmentsAreSelfContained(model); + } + + /// + /// A package contributing an entry point must be self-contained too. + /// + /// + /// Entry points are the one exported shape that names AspireClientRpc: they are free + /// functions, so the client is passed explicitly as the first parameter. The runtime fragment + /// declared every other base-library symbol but not that one, so an Aspire.Hosting export + /// published a signature naming a type no fragment declared, and aspire.dev's concatenation of + /// the manifest failed to resolve it. The context used above has no entry point, which is why + /// the sibling test never saw the gap. + /// + [Fact] + public void ApiExportDeclarationFragmentsForEntryPointsReferenceOnlyDeclaredOrBuiltInSymbols() + { + var context = CreateEntryPointContext(); + + var projector = new TypeScriptApiProjector(context); + var model = projector.BuildApiModel( + new TypeScriptApiPackageIdentity(EntryPointPackage, TestPackageVersion), + [EntryPointPackage]); + + AssertDeclarationFragmentsAreSelfContained(model); + } + + private static void AssertDeclarationFragmentsAreSelfContained(TypeScriptApiModel model) + { var declaredNames = new HashSet(StringComparer.Ordinal); foreach (var declaration in model.Declarations) diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index 0d5d4acca9f..d4a35dbc5da 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -987,4 +987,5 @@ export interface AspireDict extends HandleReference { get(key: TKe export interface ResourceBuilderBase extends HandleReference {} export interface InteractionInput { readonly name: string; } export interface InteractionInputCollection extends HandleReference {} -export interface InteractionInputCollectionPromise extends PromiseLike {} \ No newline at end of file +export interface InteractionInputCollectionPromise extends PromiseLike {} +export interface AspireClientRpc { readonly connected: boolean; invokeCapability(capabilityId: string, args?: Record): Promise; } \ No newline at end of file diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index c5a6dd2042b..998230f9b67 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -6803,7 +6803,7 @@ { "id": "aspire:runtime:base", "owningAssembly": "Aspire.Hosting", - "content": "export type Awaitable\u003CT\u003E = T | PromiseLike\u003CT\u003E;\nexport interface MarshalledHandle { $handle: string; $type: string; }\nexport interface Handle\u003CT extends string = string\u003E { readonly $handle: string; readonly $type: T; toJSON(): MarshalledHandle; }\nexport interface HandleReference { toJSON(): MarshalledHandle; }\nexport interface AbortSignal { readonly aborted: boolean; }\nexport interface CancellationToken { readonly aborted: boolean; }\nexport enum InputType { Text = \u0027Text\u0027, SecretText = \u0027SecretText\u0027, Choice = \u0027Choice\u0027, Boolean = \u0027Boolean\u0027, Number = \u0027Number\u0027 }\nexport interface ReferenceExpression { readonly value: Promise\u003Cstring\u003E; }\nexport interface AspireList\u003CT\u003E extends HandleReference { get(index: number): Promise\u003CT\u003E; }\nexport interface AspireDict\u003CTKey, TValue\u003E extends HandleReference { get(key: TKey): Promise\u003CTValue\u003E; }\nexport interface ResourceBuilderBase extends HandleReference {}\nexport interface InteractionInput { readonly name: string; }\nexport interface InteractionInputCollection extends HandleReference {}\nexport interface InteractionInputCollectionPromise extends PromiseLike\u003CInteractionInputCollection\u003E {}" + "content": "export type Awaitable\u003CT\u003E = T | PromiseLike\u003CT\u003E;\nexport interface MarshalledHandle { $handle: string; $type: string; }\nexport interface Handle\u003CT extends string = string\u003E { readonly $handle: string; readonly $type: T; toJSON(): MarshalledHandle; }\nexport interface HandleReference { toJSON(): MarshalledHandle; }\nexport interface AbortSignal { readonly aborted: boolean; }\nexport interface CancellationToken { readonly aborted: boolean; }\nexport enum InputType { Text = \u0027Text\u0027, SecretText = \u0027SecretText\u0027, Choice = \u0027Choice\u0027, Boolean = \u0027Boolean\u0027, Number = \u0027Number\u0027 }\nexport interface ReferenceExpression { readonly value: Promise\u003Cstring\u003E; }\nexport interface AspireList\u003CT\u003E extends HandleReference { get(index: number): Promise\u003CT\u003E; }\nexport interface AspireDict\u003CTKey, TValue\u003E extends HandleReference { get(key: TKey): Promise\u003CTValue\u003E; }\nexport interface ResourceBuilderBase extends HandleReference {}\nexport interface InteractionInput { readonly name: string; }\nexport interface InteractionInputCollection extends HandleReference {}\nexport interface InteractionInputCollectionPromise extends PromiseLike\u003CInteractionInputCollection\u003E {}\nexport interface AspireClientRpc { readonly connected: boolean; invokeCapability\u003CTResult = unknown\u003E(capabilityId: string, args?: Record\u003Cstring, unknown\u003E): Promise\u003CTResult\u003E; }" } ] } \ No newline at end of file diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index cd0d4567656..3bc44efda1e 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -146,7 +146,7 @@ public void ExportApi_GeneratorWithoutExporter_ReportsUnsupportedLanguage() { var service = CreateCodeGenerationService(); - // Go generates runtime source but does not implement IApiReferenceExporter, so asking it for + // Go generates runtime source but ships no IApiReferenceExporter, so asking it for // an API export has to fail with a message that names the gap rather than returning an empty // document that a documentation site would silently publish. var ex = Assert.Throws(() => service.ExportApi("Go", "Aspire.Hosting", "13.5.0")); diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs index 00ed096d64d..fb3eefb03d0 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs @@ -4,6 +4,7 @@ using Aspire.Hosting.RemoteHost.CodeGeneration; using Aspire.Hosting.RemoteHost.Diagnostics; using Aspire.Hosting.RemoteHost.Language; +using Aspire.TypeSystem; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; @@ -27,9 +28,53 @@ public void CodeGeneratorResolver_DiscoversInternalCodeGenerators() Assert.NotNull(resolver.GetCodeGenerator("TypeScript")); } + /// + /// API export is discovered as its own type, and the code generator itself must not implement + /// the exporter contract. + /// + /// + /// Aspire.TypeSystem is force-shared from the apphost server's default + /// and freezes its strong-name + /// AssemblyVersion at a constant, so a CLI that predates + /// still binds a newer SDK's codegen assembly — it just has + /// no such interface in its bundled copy. A type's interface list is resolved eagerly when the + /// type loads, so a generator implementing the interface would itself fail to load there and + /// TypeScript generation, not just export, would disappear. Keeping export on a separate type + /// confines the loss to the feature that CLI could not use anyway. + /// [Fact] - public void LanguageSupportResolver_DiscoversInternalLanguageSupports() + public void CodeGeneratorResolver_ResolvesApiReferenceExporterWithoutItLivingOnTheCodeGenerator() { + using var serviceProvider = CreateServiceProvider(); + var assemblyLoader = CreateAssemblyLoader(); + var resolver = new CodeGeneratorResolver(serviceProvider, assemblyLoader, NullLogger.Instance); + + var generator = resolver.GetCodeGenerator("TypeScript"); + Assert.NotNull(generator); + Assert.IsNotAssignableFrom(generator); + + var exporter = resolver.GetApiReferenceExporter("TypeScript"); + Assert.NotNull(exporter); + Assert.Equal("TypeScript", exporter.Language); + } + + /// + /// A documented API that no generator produces would be worse than no documentation at all, so + /// discovering exporters independently must not make one reachable for an unsupported language. + /// + [Fact] + public void CodeGeneratorResolver_DoesNotResolveAnExporterForALanguageWithNoGenerator() + { + using var serviceProvider = CreateServiceProvider(); + var assemblyLoader = CreateAssemblyLoader(); + var resolver = new CodeGeneratorResolver(serviceProvider, assemblyLoader, NullLogger.Instance); + + Assert.Null(resolver.GetCodeGenerator("Klingon")); + Assert.Null(resolver.GetApiReferenceExporter("Klingon")); + } + + [Fact] + public void LanguageSupportResolver_DiscoversInternalLanguageSupports() { using var serviceProvider = CreateServiceProvider(); var assemblyLoader = CreateAssemblyLoader(); var resolver = new LanguageSupportResolver(serviceProvider, assemblyLoader, NullLogger.Instance); From 9125b7d57c8cb8e7fe67340ba8e81229c5ccf506 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 18:14:18 -0400 Subject: [PATCH 40/73] Export the version NuGet resolves on both package paths The explicit --package path already normalized SemVer build metadata away, but the default path recorded ExecutionContext.IdentityVersion verbatim, and a real informational version carries a + suffix that NuGet does not treat as package identity. IdentitySdkVersion exists for exactly this decision. Argument parsing had the same gap in the other direction: SemVersionStyles.Any accepts abbreviated forms such as Package@2.0, which restores the 2.0.0 package while the exported document was labelled 2.0. Callers that require an exact version now record the normalized string. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkCommandPreparation.cs | 12 +++++- .../Commands/Sdk/SdkExportCommand.cs | 6 ++- .../Commands/Sdk/SdkExportCommandTests.cs | 40 ++++++++++++++++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs index fa554b28991..698061bae2f 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs @@ -78,7 +78,7 @@ public static bool TryParseIntegrationArgument( return false; } - if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out _)) + if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out var parsedVersion)) { errorMessage = requireExactVersion ? $"Invalid version '{packageVersion}' in '{argument}'. Expected an exact NuGet version (e.g. 9.2.0); floating and range versions are not supported." @@ -86,6 +86,16 @@ public static bool TryParseIntegrationArgument( return false; } + if (requireExactVersion) + { + // SemVersionStyles.Any accepts abbreviated and decorated forms -- "2.0", "v2.0.0", + // "2.01.0" -- that NuGet normalizes on restore. A caller who asks for Package@2.0 gets + // the 2.0.0 package, so recording the raw text would label the export with a version no + // feed serves. Callers that require an exact version get the normalized string, which is + // the one NuGet resolved. + packageVersion = parsedVersion.ToString(); + } + reference = IntegrationReference.FromPackage(packageName, packageVersion); return true; } diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 7370a87df7e..9bba51a7fa6 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -93,8 +93,12 @@ protected override async Task ExecuteAsync(ParseResult parseResul { // Documentation has to describe the SDK this CLI generates against, so the default is // the CLI's own identity version rather than whatever the feed currently calls latest. + // IdentitySdkVersion, not IdentityVersion: an informational version carries the build + // metadata suffix (13.4.0-preview.1.25366.3+abc123), and NuGet does not treat that as + // part of package identity, so recording it verbatim would label the export with a + // version no feed serves -- the same drift the explicit package path normalizes away. packageName = CorePackageName; - packageVersion = ExecutionContext.IdentityVersion; + packageVersion = ExecutionContext.IdentitySdkVersion; } else { diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 714f682a339..eee6e3a6486 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -71,10 +71,48 @@ public async Task SdkExportDefaultsToCoreHostingAtTheRunningSdkVersion() // Defaulting to the CLI's own SDK version is the entire point of the command: documentation // must describe the SDK this CLI would actually generate against, not a floating latest. - var expectedVersion = provider.GetRequiredService().IdentityVersion; + var expectedVersion = provider.GetRequiredService().IdentitySdkVersion; Assert.Equal(("typescript", "Aspire.Hosting", expectedVersion), rpcClient.LastExportRequest); } + [Fact] + public async Task SdkExportDefaultsToTheIdentityVersionWithoutItsBuildMetadata() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider( + interactionService, + workspace, + rpcClient, + new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName), + identityVersion: "13.5.0-dev+abc123"); + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); + + Assert.Equal(CliExitCodes.Success, exitCode); + + // A real informational version carries the commit suffix. NuGet ignores it for identity, so + // exporting under it would label the document with a version no feed serves. + Assert.Equal(("typescript", "Aspire.Hosting", "13.5.0-dev"), rpcClient.LastExportRequest); + } + + [Fact] + public async Task SdkExportPublishesTheNormalizedVersionForAnAbbreviatedRequest() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); + using var _ = workspace; + + var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + + // NuGet resolves Contoso.Aspire.Widgets@2.0 to the 2.0.0 package, so the document has to be + // keyed on the version that was actually restored. + Assert.Equal(("typescript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); + } + [Fact] public async Task SdkExportSendsProgressToStderrOnly() { From 390faaa1d3a3e7b8ad5d43e139b27234ebf6fcf6 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 18:32:39 -0400 Subject: [PATCH 41/73] Apply the projector's optionality rule to the compat guard A nullable capability parameter projects to an optional TypeScript parameter, which is why the projector and the collision guard both treat IsOptional || IsNullable as optional. The comparer still read IsOptional alone, so it called a newly added nullable parameter a breaking addition and stayed silent when a nullable parameter became non-nullable -- the transition that actually breaks callers. The two runner tests that assert on failure output now inject a writer instead of replacing Console.Error, which xUnit's parallel test classes race on. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../TypeScriptApiCompatTests.cs | 65 ++++++++++++------- .../AtsCompatibilityComparer.cs | 11 +++- .../TypeScriptApiCompatRunner.cs | 13 +++- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index af4cef079ed..16241cf5a6f 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -195,6 +195,31 @@ public void ComparerClassifiesBreakingAndAdditiveChanges() Assert.DoesNotContain(diagnostics, d => d.Symbol is "Pkg/NewThing" or "Pkg/newCapability" or "Pkg/addThing(optionalName)" or "Pkg/Options.newOptional" or "Pkg/addInputType(name)"); } + [Fact] + public void NullableCapabilityParametersUseTheSameEffectiveOptionalRuleAsTheProjector() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + WriteSurface(baselineRoot, "Pkg", """ + # Capabilities + Pkg/addThing(name: string, wasNullable: string?) -> void + """); + WriteSurface(currentRoot, "Pkg", """ + # Capabilities + Pkg/addThing(name: string, wasNullable: string, addedNullable: number?) -> void + """); + + var diagnostics = AtsCompatibilityComparer.Compare(AtsSurfaceSet.Load(baselineRoot), AtsSurfaceSet.Load(currentRoot)); + + // The projector emits a nullable parameter as `name?: type`, so dropping the nullability makes + // a parameter TypeScript callers could omit into one they cannot, and adding a nullable one + // breaks nobody. + Assert.Contains(diagnostics, d => d.Kind == "capability-parameter-required" && d.Symbol == "Pkg/addThing(wasNullable)"); + Assert.DoesNotContain(diagnostics, d => d.Kind == "capability-parameter-added-required"); + } + [Fact] public void SuppressionsUseExactMatchesAndFailWhenUnused() { @@ -352,27 +377,23 @@ public void RunnerFailsWhenUnqualifiedOptionsInterfaceNamesCollide() Pkg.Two/withShared(host?: string) -> void """); + // The writer is injected rather than swapped in through Console.SetError: xUnit runs test + // classes in parallel, so replacing the process-wide console lets one test capture another + // test's output and lets another test restore the writer mid-assertion. using var error = new StringWriter(); - var originalError = Console.Error; - try - { - Console.SetError(error); - var exitCode = TypeScriptApiCompatRunner.Run(new CommandLineOptions( + var exitCode = TypeScriptApiCompatRunner.Run( + new CommandLineOptions( baselineRoot, currentRoot, workspace.Path, BaselineSuppressionsRoot: null, ExcludedPackagesFile: null, ReportPath: null, - GitHubAnnotations: false)); + GitHubAnnotations: false), + error); - Assert.Equal(2, exitCode); - } - finally - { - Console.SetError(originalError); - } + Assert.Equal(2, exitCode); var message = error.ToString(); Assert.Contains("Unqualified TypeScript options interface collision", message, StringComparison.Ordinal); @@ -406,27 +427,23 @@ public void RunnerFailsWhenNullableParametersProduceUnqualifiedOptionsInterfaceC Pkg.Two/withShared(host: string?) -> void """); + // The writer is injected rather than swapped in through Console.SetError: xUnit runs test + // classes in parallel, so replacing the process-wide console lets one test capture another + // test's output and lets another test restore the writer mid-assertion. using var error = new StringWriter(); - var originalError = Console.Error; - try - { - Console.SetError(error); - var exitCode = TypeScriptApiCompatRunner.Run(new CommandLineOptions( + var exitCode = TypeScriptApiCompatRunner.Run( + new CommandLineOptions( baselineRoot, currentRoot, workspace.Path, BaselineSuppressionsRoot: null, ExcludedPackagesFile: null, ReportPath: null, - GitHubAnnotations: false)); + GitHubAnnotations: false), + error); - Assert.Equal(2, exitCode); - } - finally - { - Console.SetError(originalError); - } + Assert.Equal(2, exitCode); var message = error.ToString(); Assert.Contains("WithSharedOptions", message, StringComparison.Ordinal); diff --git a/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs b/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs index a343b775891..ec9c206ea4b 100644 --- a/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs +++ b/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs @@ -234,6 +234,13 @@ private static void CompareCapabilities(AtsSurface baseline, AtsSurface current, } } + // A nullable parameter projects to an optional TypeScript parameter (`name?: type`), so the + // TypeScript projector treats IsOptional || IsNullable as optional. Comparing on IsOptional alone + // would call a newly added nullable parameter a breaking addition and would miss a nullable + // parameter becoming non-nullable, which really does break existing callers. + private static bool IsEffectivelyOptional(AtsParameter parameter) + => parameter.IsOptional || parameter.IsNullable; + private static void CompareCapabilityParameters( string packageName, AtsCapability baselineCapability, @@ -265,7 +272,7 @@ private static void CompareCapabilityParameters( $"Capability parameter '{symbol}' type changed from '{baselineParameter.TypeId}' to '{currentParameter.TypeId}'.")); } - if (baselineParameter.IsOptional && !currentParameter.IsOptional) + if (IsEffectivelyOptional(baselineParameter) && !IsEffectivelyOptional(currentParameter)) { diagnostics.Add(new ApiCompatDiagnostic( "capability-parameter-required", @@ -277,7 +284,7 @@ private static void CompareCapabilityParameters( foreach (var currentParameter in currentCapability.Parameters) { - if (!currentParameter.IsOptional && !baselineByName.ContainsKey(currentParameter.Name)) + if (!IsEffectivelyOptional(currentParameter) && !baselineByName.ContainsKey(currentParameter.Name)) { var symbol = $"{baselineCapability.CapabilityId}({currentParameter.Name})"; diagnostics.Add(new ApiCompatDiagnostic( diff --git a/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs b/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs index 2dd4386923c..d467fc1efca 100644 --- a/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs +++ b/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs @@ -5,7 +5,16 @@ namespace TypeScriptApiCompat; internal static class TypeScriptApiCompatRunner { - public static int Run(CommandLineOptions options) + /// + /// Runs the TypeScript API compatibility comparison and writes its report. + /// + /// The parsed command line options. + /// + /// Where failure messages go. Defaults to for the command line, and is + /// injected by tests so they can read the message without replacing the process-wide console, + /// which xUnit's parallel classes would otherwise race on. + /// + public static int Run(CommandLineOptions options, TextWriter? errorWriter = null) { try { @@ -43,7 +52,7 @@ public static int Run(CommandLineOptions options) } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or InvalidDataException or InvalidOperationException) { - Console.Error.WriteLine(ex.Message); + (errorWriter ?? Console.Error).WriteLine(ex.Message); return 2; } } From c9061a21481e8608df4544c97d3e09231e877fe5 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 19:06:40 -0400 Subject: [PATCH 42/73] Send the generator name the server keys on The export RPC forwarded whatever the user typed for --language, but RemoteHost resolves generators by ICodeGenerator.Language ("TypeScript"). Discovery already accepted the canonical language id, so `aspire sdk export --language typescript/nodejs` restored the right code generation package and then failed on the far side with "No code generator found". The matched LanguageInfo now supplies the name that crosses the wire, the way `sdk generate` already does. An unresolved language is still forwarded verbatim so the server produces the authoritative unsupported-language error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkExportCommand.cs | 46 +++++++++++++------ .../Commands/Sdk/SdkExportCommandTests.cs | 42 +++++++++++++---- 2 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 9bba51a7fa6..0d0954de39f 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -164,14 +164,23 @@ protected override async Task ExecuteAsync(ParseResult parseResul // The code generator lives in a separate package that the scanner AppHost does not reference // by default, so without this the server loads no generators and every export fails with // "No code generator found". `sdk generate` adds the same package for the same reason. - var codeGenPackage = await GetCodeGenerationPackageAsync(language, cancellationToken); + var languageInfo = await GetLanguageInfoAsync(language, cancellationToken); + var codeGenPackage = languageInfo is null + ? null + : await GetCodeGenerationPackageAsync(languageInfo, cancellationToken); if (codeGenPackage is not null) { integrations.Add(IntegrationReference.FromExactPackage(codeGenPackage, ExecutionContext.IdentityVersion)); } + // The server keys generators by ICodeGenerator.Language ("TypeScript"), not by the language + // id or the abbreviation the user typed, so the matched generator name is what crosses the + // RPC. `aspire sdk export --language typescript/nodejs` resolves its package here and would + // otherwise fail with "No code generator found" on the far side. `sdk generate` sends the + // same value. An unresolved language is forwarded verbatim so the server produces the + // authoritative unsupported-language error rather than this command guessing at one. return CommandResult.FromExitCode(await ExportApiAsync( - language, + languageInfo?.CodeGenerator ?? language, packageName, packageVersion, integrations, @@ -182,30 +191,41 @@ protected override async Task ExecuteAsync(ParseResult parseResul } /// - /// Resolves the code generation package that provides the requested language, matching the way - /// sdk generate resolves it. Returns when the language is unknown so - /// that the server produces the authoritative unsupported-language error. + /// Resolves the language the user asked for, matching the way sdk generate resolves it. + /// Returns when the language is unknown so that the server produces the + /// authoritative unsupported-language error. /// - private async Task GetCodeGenerationPackageAsync(string language, CancellationToken cancellationToken) + private async Task GetLanguageInfoAsync(string language, CancellationToken cancellationToken) { try { var languages = await _languageDiscovery.GetAvailableLanguagesAsync(cancellationToken); - var languageInfo = languages.FirstOrDefault(l => + return languages.FirstOrDefault(l => l.LanguageId.Value.StartsWith(language, StringComparison.OrdinalIgnoreCase) || l.CodeGenerator.Equals(language, StringComparison.OrdinalIgnoreCase)); + } + catch (Exception ex) when (ex is not OperationCanceledException) + { + _logger.LogDebug(ex, "Failed to resolve the language {Language}", language); + return null; + } + } - if (languageInfo is null) - { - return null; - } - + /// + /// Resolves the code generation package that provides the requested language. Returns + /// when discovery fails so that the export still runs and the server + /// reports the missing generator. + /// + private async Task GetCodeGenerationPackageAsync(LanguageInfo languageInfo, CancellationToken cancellationToken) + { + try + { return await _languageDiscovery.GetPackageForLanguageAsync(languageInfo.LanguageId, cancellationToken); } catch (Exception ex) when (ex is not OperationCanceledException) { - _logger.LogDebug(ex, "Failed to resolve the code generation package for language {Language}", language); + _logger.LogDebug(ex, "Failed to resolve the code generation package for language {Language}", languageInfo.LanguageId.Value); return null; } } diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index eee6e3a6486..09ef2e11cf7 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -39,6 +39,28 @@ public async Task SdkExportWithHelpReturnsZero() Assert.Equal(0, exitCode); } + /// + /// The server keys generators by ICodeGenerator.Language, so every accepted spelling of a + /// language has to arrive there as the generator name. The canonical language id is the spelling + /// most likely to be typed and the one furthest from the generator name. + /// + [Theory] + [InlineData("typescript/nodejs")] + [InlineData("typescript")] + [InlineData("TypeScript")] + public async Task SdkExportSendsTheGeneratorNameForEveryAcceptedLanguageSpelling(string language) + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); + using var _ = workspace; + + var exitCode = await InvokeAsync(provider, $"sdk export --language {language}"); + + Assert.Equal(CliExitCodes.Success, exitCode); + var request = Assert.NotNull(rpcClient.LastExportRequest); + Assert.Equal("TypeScript", request.Language); + } + [Fact] public async Task SdkExportForExactPackageWritesCanonicalDocumentToStdout() { @@ -50,7 +72,7 @@ public async Task SdkExportForExactPackageWritesCanonicalDocumentToStdout() var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion}"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("typescript", "Aspire.Hosting.Redis", packageVersion), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Aspire.Hosting.Redis", packageVersion), rpcClient.LastExportRequest); var stdout = Assert.Single(interactionService.DisplayedRawText, entry => entry.ConsoleOverride == ConsoleOutput.Standard); using var document = JsonDocument.Parse(stdout.Text); @@ -72,7 +94,7 @@ public async Task SdkExportDefaultsToCoreHostingAtTheRunningSdkVersion() // Defaulting to the CLI's own SDK version is the entire point of the command: documentation // must describe the SDK this CLI would actually generate against, not a floating latest. var expectedVersion = provider.GetRequiredService().IdentitySdkVersion; - Assert.Equal(("typescript", "Aspire.Hosting", expectedVersion), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Aspire.Hosting", expectedVersion), rpcClient.LastExportRequest); } [Fact] @@ -94,7 +116,7 @@ public async Task SdkExportDefaultsToTheIdentityVersionWithoutItsBuildMetadata() // A real informational version carries the commit suffix. NuGet ignores it for identity, so // exporting under it would label the document with a version no feed serves. - Assert.Equal(("typescript", "Aspire.Hosting", "13.5.0-dev"), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Aspire.Hosting", "13.5.0-dev"), rpcClient.LastExportRequest); } [Fact] @@ -110,7 +132,7 @@ public async Task SdkExportPublishesTheNormalizedVersionForAnAbbreviatedRequest( // NuGet resolves Contoso.Aspire.Widgets@2.0 to the 2.0.0 package, so the document has to be // keyed on the version that was actually restored. - Assert.Equal(("typescript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); } [Fact] @@ -231,7 +253,7 @@ public async Task SdkExportAcceptsCoreVersionThatDiffersOnlyByBuildMetadata() // The metadata is accepted but must not survive into the document: see // SdkExportPublishesTheVersionNuGetResolvesRatherThanTheRequestedBuildMetadata. Assert.Equal( - ("typescript", "Aspire.Hosting", executionContext.IdentitySdkVersion), + ("TypeScript", "Aspire.Hosting", executionContext.IdentitySdkVersion), rpcClient.LastExportRequest); } @@ -255,7 +277,7 @@ public async Task SdkExportPublishesTheVersionNuGetResolvesRatherThanTheRequeste "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0+fake"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("typescript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); var requested = Assert.Single( appHostServerProject.Integrations, @@ -326,7 +348,7 @@ public async Task SdkExportForASubstitutedPackageAtTheCheckoutVersionSucceeds() var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{checkoutVersion}"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("typescript", "Aspire.Hosting.Redis", checkoutVersion), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Aspire.Hosting.Redis", checkoutVersion), rpcClient.LastExportRequest); } [Fact] @@ -371,7 +393,7 @@ public async Task SdkExportAllowsASubstitutedGeneratorAtTheCheckoutVersion() var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("typescript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); } [Fact] @@ -624,7 +646,7 @@ public async Task SdkExportOfTheCorePackageIsPublishedUnderItsCanonicalNameWhate var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package aspire.hosting@13.5.0"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("typescript", "Aspire.Hosting", "13.5.0"), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Aspire.Hosting", "13.5.0"), rpcClient.LastExportRequest); var stdout = Assert.Single(interactionService.DisplayedRawText, entry => entry.ConsoleOverride == ConsoleOutput.Standard); using var document = JsonDocument.Parse(stdout.Text); @@ -673,7 +695,7 @@ public async Task SdkExportForAThirdPartyPackageIsUnaffectedByCheckoutSubstituti "sdk export --language typescript --package CommunityToolkit.Aspire.Hosting.ActiveMQ@13.4.0"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("typescript", "CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0"), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0"), rpcClient.LastExportRequest); } /// From f88c123da74966e20a774a20fde7a47b7886bf99 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 19:31:18 -0400 Subject: [PATCH 43/73] Check the options interface the generator will actually emit The collision guard derived the options interface name from the capability id, but the projector names it after the projected method, which [AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] makes differ. So the guard checked WithRedisCommanderHostPortOptions while the generator emits WithHostPortOptions, and a real cross-package collision between Redis, PostgreSQL and Yarp would go unseen. The CI surface only recorded the id, so `sdk dump --format ci` now names the projected method when it differs -- an annotation only the aliased minority carries, leaving every other surface line byte-identical. The parser splits it off the return type so pre-existing baselines still compare clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .commitmsg | 15 +++ src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs | 17 ++- .../Commands/SdkDumpCommandTests.cs | 32 +++++ .../TypeScriptApiCompatTests.cs | 114 ++++++++++++++++++ tools/TypeScriptApiCompat/AtsSurface.cs | 14 ++- tools/TypeScriptApiCompat/AtsSurfaceParser.cs | 24 +++- .../TypeScriptOptionsCollisionGuard.cs | 16 +-- 7 files changed, 221 insertions(+), 11 deletions(-) create mode 100644 .commitmsg diff --git a/.commitmsg b/.commitmsg new file mode 100644 index 00000000000..a653a802ee5 --- /dev/null +++ b/.commitmsg @@ -0,0 +1,15 @@ +Check the options interface the generator will actually emit + +The collision guard derived the options interface name from the capability +id, but the projector names it after the projected method, which +[AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] +makes differ. So the guard checked WithRedisCommanderHostPortOptions while +the generator emits WithHostPortOptions, and a real cross-package collision +between Redis, PostgreSQL and Yarp would go unseen. + +The CI surface only recorded the id, so `sdk dump --format ci` now names the +projected method when it differs -- an annotation only the aliased minority +carries, leaving every other surface line byte-identical. The parser splits +it off the return type so pre-existing baselines still compare clean. + +Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> diff --git a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs index 81cbc7e3e3e..0b9497261cc 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs @@ -425,12 +425,27 @@ private static string FormatCi(CapabilitiesInfo capabilities) return string.Format(CultureInfo.InvariantCulture, "{0}{1}: {2}{3}", p.Name, optional, p.Type?.TypeId ?? "unknown", nullable); })); var returnStr = c.ReturnType?.TypeId ?? "void"; - sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0}({1}) -> {2}", c.CapabilityId, paramStr, returnStr)); + + // [AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] makes the + // projected TypeScript name differ from the capability id, and the generated options + // interface is named after the projected name. The annotation is emitted only for that + // aliased minority so the surface stays unchanged for everything else: + // Pkg/withRedisCommanderHostPort(port?: number) -> Pkg/Handle [method=withHostPort] + var methodSuffix = string.IsNullOrEmpty(c.MethodName) || string.Equals(c.MethodName, GetCapabilityMethodSegment(c.CapabilityId), StringComparison.Ordinal) + ? "" + : string.Format(CultureInfo.InvariantCulture, " [method={0}]", c.MethodName); + sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0}({1}) -> {2}{3}", c.CapabilityId, paramStr, returnStr, methodSuffix)); } return sb.ToString(); } + private static string GetCapabilityMethodSegment(string capabilityId) + { + var slashIndex = capabilityId.IndexOf('/'); + return slashIndex < 0 ? capabilityId : capabilityId[(slashIndex + 1)..]; + } + private static string FormatPretty(CapabilitiesInfo capabilities) { var sb = new StringBuilder(); diff --git a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs index 540e1bcb013..d1d8b65efbb 100644 --- a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs @@ -363,6 +363,38 @@ public void FormatCi_MarksNullableCapabilityParameters() Assert.Contains("Pkg/withNullable(name: string?) -> void", output); } + [Theory] + [InlineData("withHostPort", "Pkg/withRedisCommanderHostPort(port: number) -> void [method=withHostPort]")] + [InlineData("withRedisCommanderHostPort", "Pkg/withRedisCommanderHostPort(port: number) -> void")] + [InlineData("", "Pkg/withRedisCommanderHostPort(port: number) -> void")] + public void FormatCi_NamesTheProjectedMethodOnlyWhenItDiffersFromTheCapabilityId(string methodName, string expectedLine) + { + var capabilities = new CapabilitiesInfo + { + Capabilities = + [ + new CapabilityInfo + { + CapabilityId = "Pkg/withRedisCommanderHostPort", + MethodName = methodName, + Parameters = + [ + new Aspire.Cli.Commands.Sdk.ParameterInfo + { + Name = "port", + Type = new TypeRefInfo { TypeId = "number" } + } + ], + ReturnType = new TypeRefInfo { TypeId = "void" } + } + ] + }; + + var output = InvokeFormatter("FormatCi", capabilities); + + Assert.Contains(expectedLine, output, StringComparison.Ordinal); + } + [Fact] public void FormatPretty_IncludesExportedValues() { diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index 16241cf5a6f..7d8ce43e647 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -451,6 +451,120 @@ public void RunnerFailsWhenNullableParametersProduceUnqualifiedOptionsInterfaceC Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); } + [Fact] + public void RunnerFailsWhenAliasedCapabilitiesProjectToTheSameOptionsInterface() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + // Both packages alias distinct capability ids onto the same projected method, which is what + // [AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] does. The ids do + // not collide; the generated WithHostPortOptions interfaces do. + foreach (var root in new[] { baselineRoot, currentRoot }) + { + WriteSurface(root, "Pkg.One", """ + # Capabilities + Pkg.One/withCommanderHostPort(port?: number) -> void [method=withHostPort] + """); + WriteSurface(root, "Pkg.Two", """ + # Capabilities + Pkg.Two/withInsightHostPort(port?: number) -> void [method=withHostPort] + """); + } + + using var error = new StringWriter(); + + var exitCode = TypeScriptApiCompatRunner.Run( + new CommandLineOptions( + baselineRoot, + currentRoot, + workspace.Path, + BaselineSuppressionsRoot: null, + ExcludedPackagesFile: null, + ReportPath: null, + GitHubAnnotations: false), + error); + + Assert.Equal(2, exitCode); + + var message = error.ToString(); + Assert.Contains("WithHostPortOptions", message, StringComparison.Ordinal); + Assert.Contains("'Pkg.One'", message, StringComparison.Ordinal); + Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); + } + + [Fact] + public void RunnerAllowsSharedCapabilityIdsThatProjectToDifferentMethodNames() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + foreach (var root in new[] { baselineRoot, currentRoot }) + { + WriteSurface(root, "Pkg.One", """ + # Capabilities + Pkg.One/withShared(port?: number) -> void [method=withOnePort] + """); + WriteSurface(root, "Pkg.Two", """ + # Capabilities + Pkg.Two/withShared(host?: string) -> void [method=withTwoHost] + """); + } + + using var error = new StringWriter(); + + var exitCode = TypeScriptApiCompatRunner.Run( + new CommandLineOptions( + baselineRoot, + currentRoot, + workspace.Path, + BaselineSuppressionsRoot: null, + ExcludedPackagesFile: null, + ReportPath: null, + GitHubAnnotations: false), + error); + + Assert.Equal(0, exitCode); + Assert.DoesNotContain("collision", error.ToString(), StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ComparerTreatsTheProjectedMethodAnnotationAsSurfaceMetadataRatherThanTheReturnType() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + // Baselines written before the annotation existed carry no [method=...] suffix, so the + // annotation has to be split off the return type or every aliased capability would look + // like its return type changed the first time a surface is regenerated. + WriteSurface(baselineRoot, "Pkg", """ + # Capabilities + Pkg/withCommanderHostPort(port?: number) -> void + """); + WriteSurface(currentRoot, "Pkg", """ + # Capabilities + Pkg/withCommanderHostPort(port?: number) -> void [method=withHostPort] + """); + + using var error = new StringWriter(); + + var exitCode = TypeScriptApiCompatRunner.Run( + new CommandLineOptions( + baselineRoot, + currentRoot, + workspace.Path, + BaselineSuppressionsRoot: null, + ExcludedPackagesFile: null, + ReportPath: null, + GitHubAnnotations: false), + error); + + Assert.Equal(0, exitCode); + } + private static void WriteSurface(string rootPath, string packageName, string content) { var apiDirectory = Path.Combine(rootPath, "src", packageName, "api"); diff --git a/tools/TypeScriptApiCompat/AtsSurface.cs b/tools/TypeScriptApiCompat/AtsSurface.cs index 65cdf042b1e..87c907bfaa7 100644 --- a/tools/TypeScriptApiCompat/AtsSurface.cs +++ b/tools/TypeScriptApiCompat/AtsSurface.cs @@ -21,7 +21,19 @@ internal sealed record AtsEnumType(string TypeId, IReadOnlyList Values); internal sealed record AtsExportedValue(string Path, string TypeId, string Value); -internal sealed record AtsCapability(string CapabilityId, IReadOnlyList Parameters, string ReturnTypeId); +/// The exported capability id, for example Pkg/withRedisCommanderHostPort. +/// The exported parameters, in declaration order. +/// The exported return type id. +/// +/// The TypeScript method name the projector emits, which [AspireExport(..., MethodName = "...")] +/// can make differ from the capability id. This is what the options interface is named after, so the +/// collision guard has to use it rather than the id. +/// +internal sealed record AtsCapability( + string CapabilityId, + IReadOnlyList Parameters, + string ReturnTypeId, + string ProjectedMethodName); internal sealed record AtsParameter(string Name, string TypeId, bool IsOptional, bool IsNullable); diff --git a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs index 7e4640db9e1..8861ac019a8 100644 --- a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs +++ b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs @@ -207,7 +207,29 @@ private static AtsCapability ParseCapability(string line) .Select(ParseParameter) .ToArray(); - return new AtsCapability(capabilityId, parameters, returnTypeId); + // A capability whose projected TypeScript method name differs from its id carries that name + // as a trailing annotation: + // Pkg/withRedisCommanderHostPort(port?: number) -> Pkg/Handle [method=withHostPort] + // The annotation is emitted only for the aliased minority, so an unannotated line -- every + // line in a surface written before this existed -- projects under its own id. + var projectedMethodName = GetMethodNameSegment(capabilityId); + var annotationIndex = returnTypeId.IndexOf(MethodAnnotationPrefix, StringComparison.Ordinal); + if (annotationIndex >= 0 && returnTypeId.EndsWith(']')) + { + var start = annotationIndex + MethodAnnotationPrefix.Length; + projectedMethodName = returnTypeId[start..^1]; + returnTypeId = returnTypeId[..annotationIndex]; + } + + return new AtsCapability(capabilityId, parameters, returnTypeId, projectedMethodName); + } + + private const string MethodAnnotationPrefix = " [method="; + + private static string GetMethodNameSegment(string capabilityId) + { + var slashIndex = capabilityId.IndexOf('/'); + return slashIndex < 0 ? capabilityId : capabilityId[(slashIndex + 1)..]; } private static AtsParameter ParseParameter(string parameterText) diff --git a/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs b/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs index d6a42255b26..e46a61f7b04 100644 --- a/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs +++ b/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs @@ -28,7 +28,12 @@ public static void Validate(AtsSurfaceSet surfaceSet) continue; } - var interfaceName = GetUnqualifiedOptionsInterfaceName(capability.CapabilityId); + // The options interface is named after the projected method name, which + // [AspireExport(..., MethodName = "...")] can make differ from the capability id: + // Redis Commander exports withRedisCommanderHostPort but projects as withHostPort, + // so naming from the id would check WithRedisCommanderHostPortOptions while the + // generator emits WithHostPortOptions and the real collision goes unseen. + var interfaceName = GetUnqualifiedOptionsInterfaceName(capability.ProjectedMethodName); if (!TypeScriptOptionsInterfaceNaming.RequiresPackageQualifier(interfaceName)) { candidates.Add(new OptionsInterfaceCandidate(interfaceName, surface.PackageName, capability.CapabilityId)); @@ -64,13 +69,8 @@ private static bool IsDirectOptionsParameter(IReadOnlyList options dtoTypeIds.Contains(candidates[0].TypeId); } - private static string GetUnqualifiedOptionsInterfaceName(string capabilityId) - { - var slashIndex = capabilityId.IndexOf('/'); - var methodName = slashIndex < 0 ? capabilityId : capabilityId[(slashIndex + 1)..]; - - return TypeScriptOptionsInterfaceNaming.GetUnqualifiedOptionsInterfaceName(methodName); - } + private static string GetUnqualifiedOptionsInterfaceName(string projectedMethodName) + => TypeScriptOptionsInterfaceNaming.GetUnqualifiedOptionsInterfaceName(projectedMethodName); private static string CreateCollisionMessage(IReadOnlyList collisions) { From a3c517f469ee3fa768df41f40c5f6cc1bee8388b Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 19:49:10 -0400 Subject: [PATCH 44/73] Remove the stray commit-message scratch file A `git add -A` swept the temporary file used to author the previous commit message into the tree. It is not consumed by the build or the feature. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .commitmsg | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .commitmsg diff --git a/.commitmsg b/.commitmsg deleted file mode 100644 index a653a802ee5..00000000000 --- a/.commitmsg +++ /dev/null @@ -1,15 +0,0 @@ -Check the options interface the generator will actually emit - -The collision guard derived the options interface name from the capability -id, but the projector names it after the projected method, which -[AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] -makes differ. So the guard checked WithRedisCommanderHostPortOptions while -the generator emits WithHostPortOptions, and a real cross-package collision -between Redis, PostgreSQL and Yarp would go unseen. - -The CI surface only recorded the id, so `sdk dump --format ci` now names the -projected method when it differs -- an annotation only the aliased minority -carries, leaving every other surface line byte-identical. The parser splits -it off the return type so pre-existing baselines still compare clean. - -Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> From 1374c3f798ab5c34c9a837cb7c10a06d9380ca74 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 19:57:59 -0400 Subject: [PATCH 45/73] Stop resolving a blank --language to whichever came first alphabetically Every language id starts with the empty string, so the prefix match turned `--language ""` into the first discovered language and then tried to restore a generator package for it. That threw ArgumentException and surfaced as "An unexpected error occurred" rather than the unsupported-language error the server is supposed to produce. `sdk generate` matches the same way and had the same hole. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkExportCommand.cs | 9 +++++++ .../Commands/Sdk/SdkGenerateCommand.cs | 7 +++++ .../Commands/Sdk/SdkExportCommandTests.cs | 26 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 0d0954de39f..c285e1024dc 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -197,6 +197,15 @@ protected override async Task ExecuteAsync(ParseResult parseResul /// private async Task GetLanguageInfoAsync(string language, CancellationToken cancellationToken) { + // --language is required, but System.CommandLine considers `--language ""` supplied, and + // every language id starts with the empty string. Without this guard the prefix match would + // hand back whichever language happened to be discovered first and export it as though the + // user had asked for it. + if (string.IsNullOrWhiteSpace(language)) + { + return null; + } + try { var languages = await _languageDiscovery.GetAvailableLanguagesAsync(cancellationToken); diff --git a/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs index 10ba5300625..379e3115fd9 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs @@ -94,6 +94,13 @@ protected override async Task ExecuteAsync(ParseResult parseResul private async Task GetLanguageInfoAsync(string language, CancellationToken cancellationToken) { + // Every language id starts with the empty string, so an explicitly blank --language would + // otherwise resolve to whichever language was discovered first. + if (string.IsNullOrWhiteSpace(language)) + { + return null; + } + var languages = await _languageDiscovery.GetAvailableLanguagesAsync(cancellationToken); // Match by language ID or code generator name diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 09ef2e11cf7..7d8611aea65 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -196,6 +196,32 @@ public async Task SdkExportAddsTheCodeGenerationPackageForTheRequestedLanguage() integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); } + [Theory] + [InlineData("\"\"")] + [InlineData("\" \"")] + public async Task SdkExportDoesNotResolveABlankLanguageToTheFirstDiscoveredOne(string language) + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + + var exitCode = await InvokeAsync(provider, $"sdk export --language {language}"); + + // Every language id starts with the empty string, so the prefix match resolved `--language ""` + // to whichever language was discovered first and then tried to restore a generator package for + // it, which threw ArgumentException and surfaced as "An unexpected error occurred". A blank + // value has to stay unresolved and travel verbatim so the server produces the authoritative + // unsupported-language error instead. + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Empty(interactionService.DisplayedErrors); + Assert.DoesNotContain( + appHostServerProject.Integrations, + integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); + Assert.Equal("", rpcClient.LastExportRequest?.Language?.Trim()); + } + [Theory] [InlineData("Aspire.Hosting")] [InlineData("Aspire.Hosting@")] From d218959475647e810ffe128a6d722caac1ef276b Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 20:12:47 -0400 Subject: [PATCH 46/73] Catch a projected method rename the capability id hides The annotation the collision guard reads was not compared, so renaming [method=withHostPort] to [method=withOtherPort] would rename the generated TypeScript method while the compatibility check exited clean. It is compared only when the baseline recorded it, because an unannotated baseline has the name inferred from the id and would otherwise report every aliased export as renamed on the single regeneration that first writes the annotations. Also corrects the export sdkVersion comment. Neither scanner project reads that value -- the exact integration reference and the restorability validation are what tie the export to the requested SDK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkExportCommand.cs | 8 +++- .../TypeScriptApiCompatTests.cs | 37 +++++++++++++++++++ .../AtsCompatibilityComparer.cs | 15 ++++++++ tools/TypeScriptApiCompat/AtsSurface.cs | 9 ++++- tools/TypeScriptApiCompat/AtsSurfaceParser.cs | 4 +- 5 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index c285e1024dc..4b10a3345ae 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -430,8 +430,12 @@ private async Task ExportApiAsync( FileInfo? outputFile, CancellationToken cancellationToken) { - // The AppHost is restored at the version being documented so the export describes that exact - // SDK, not the CLI's bundled one. + // Both scanner projects ignore this value -- DotNetBasedAppHostServerProject.PrepareAsync + // never reads it, and PrebuiltAppHostServer restores from the integration references alone -- + // so it is a label, not a pin. What actually makes the export describe the requested SDK is + // the exact IntegrationReference above plus ValidateRequestedPackageIsRestorable below. It is + // still derived from the documented version so any consumer that starts honoring it agrees + // with what was exported rather than with the CLI's bundled SDK. var sdkVersion = string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase) ? packageVersion : ExecutionContext.IdentityVersion; diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index 7d8ce43e647..978431dc5ce 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -565,6 +565,43 @@ public void ComparerTreatsTheProjectedMethodAnnotationAsSurfaceMetadataRatherTha Assert.Equal(0, exitCode); } + [Fact] + public void ComparerReportsARenamedProjectedMethodOnceTheBaselineRecordsIt() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + // The capability id is unchanged, so nothing else in the comparison notices -- but the + // generated TypeScript method is renamed, which breaks callers exactly like a removal. + WriteSurface(baselineRoot, "Pkg", """ + # Capabilities + Pkg/withCommanderHostPort(port?: number) -> void [method=withHostPort] + """); + WriteSurface(currentRoot, "Pkg", """ + # Capabilities + Pkg/withCommanderHostPort(port?: number) -> void [method=withOtherPort] + """); + + var reportPath = Path.Combine(workspace.Path, "report.md"); + + var exitCode = TypeScriptApiCompatRunner.Run(new CommandLineOptions( + baselineRoot, + currentRoot, + workspace.Path, + BaselineSuppressionsRoot: null, + ExcludedPackagesFile: null, + ReportPath: reportPath, + GitHubAnnotations: false)); + + Assert.Equal(1, exitCode); + + var report = File.ReadAllText(reportPath); + Assert.Contains("capability-method-renamed", report, StringComparison.Ordinal); + Assert.Contains("withHostPort", report, StringComparison.Ordinal); + Assert.Contains("withOtherPort", report, StringComparison.Ordinal); + } + private static void WriteSurface(string rootPath, string packageName, string content) { var apiDirectory = Path.Combine(rootPath, "src", packageName, "api"); diff --git a/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs b/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs index ec9c206ea4b..7932ec3ff33 100644 --- a/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs +++ b/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs @@ -230,6 +230,21 @@ private static void CompareCapabilities(AtsSurface baseline, AtsSurface current, $"Capability '{capabilityId}' return type changed from '{baselineCapability.ReturnTypeId}' to '{currentCapability.ReturnTypeId}'.")); } + // Renaming the projected method renames the generated TypeScript method even though the + // capability id is unchanged, so it breaks callers exactly like a removal would. Only an + // annotated baseline can be compared: an unannotated one has the name inferred from the + // id, so comparing it would report every aliased export as renamed on the single + // regeneration that first writes the annotations. + if (baselineCapability.ProjectedMethodNameWasRecorded && + !string.Equals(baselineCapability.ProjectedMethodName, currentCapability.ProjectedMethodName, StringComparison.Ordinal)) + { + diagnostics.Add(new ApiCompatDiagnostic( + "capability-method-renamed", + baseline.PackageName, + capabilityId, + $"Capability '{capabilityId}' projected method name changed from '{baselineCapability.ProjectedMethodName}' to '{currentCapability.ProjectedMethodName}'.")); + } + CompareCapabilityParameters(baseline.PackageName, baselineCapability, currentCapability, diagnostics); } } diff --git a/tools/TypeScriptApiCompat/AtsSurface.cs b/tools/TypeScriptApiCompat/AtsSurface.cs index 87c907bfaa7..7cfd2e1a6fa 100644 --- a/tools/TypeScriptApiCompat/AtsSurface.cs +++ b/tools/TypeScriptApiCompat/AtsSurface.cs @@ -29,11 +29,18 @@ internal sealed record AtsExportedValue(string Path, string TypeId, string Value /// can make differ from the capability id. This is what the options interface is named after, so the /// collision guard has to use it rather than the id. /// +/// +/// Whether the surface actually carried the projected name rather than having it inferred from the +/// capability id. Surfaces written before the annotation existed carry nothing, and comparing an +/// inferred name against a recorded one would report every aliased export as renamed the first time +/// a baseline is regenerated. +/// internal sealed record AtsCapability( string CapabilityId, IReadOnlyList Parameters, string ReturnTypeId, - string ProjectedMethodName); + string ProjectedMethodName, + bool ProjectedMethodNameWasRecorded); internal sealed record AtsParameter(string Name, string TypeId, bool IsOptional, bool IsNullable); diff --git a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs index 8861ac019a8..600fec0fde2 100644 --- a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs +++ b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs @@ -213,15 +213,17 @@ private static AtsCapability ParseCapability(string line) // The annotation is emitted only for the aliased minority, so an unannotated line -- every // line in a surface written before this existed -- projects under its own id. var projectedMethodName = GetMethodNameSegment(capabilityId); + var projectedMethodNameWasRecorded = false; var annotationIndex = returnTypeId.IndexOf(MethodAnnotationPrefix, StringComparison.Ordinal); if (annotationIndex >= 0 && returnTypeId.EndsWith(']')) { var start = annotationIndex + MethodAnnotationPrefix.Length; projectedMethodName = returnTypeId[start..^1]; returnTypeId = returnTypeId[..annotationIndex]; + projectedMethodNameWasRecorded = true; } - return new AtsCapability(capabilityId, parameters, returnTypeId, projectedMethodName); + return new AtsCapability(capabilityId, parameters, returnTypeId, projectedMethodName, projectedMethodNameWasRecorded); } private const string MethodAnnotationPrefix = " [method="; From d80f301b2a49299a49c796dd0ea8e55007f3412a Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 20:29:04 -0400 Subject: [PATCH 47/73] Terminate the options interface qualifier Concatenating the escaped assembly name straight onto the unqualified name is not injective at the seam: assembly Contoso with method fooBar and assembly ContosoFoo with method bar both produced ContosoFooBarOptions, and the collision guard only inspects unqualified names, so two packages could contribute conflicting declarations under one symbol. Emit '$' between the two parts. Every non-alphanumeric code unit in the qualifier is escaped as _xNNNN_, so '$' can never occur inside it and the first '$' is always the seam. Teach the two \w-based identifier regexes about it so a qualified name is not captured as its qualifier alone. --- .../TypeScriptApiProjector.cs | 19 +++++-- .../AtsTypeScriptCodeGeneratorTests.cs | 50 ++++++++++++------- .../Snapshots/AtsGeneratedAspire.verified.ts | 28 +++++------ ...eneratorTests.ApiDeclarations.verified.txt | 16 +++--- ...CodeGeneratorTests.ApiExport.verified.json | 42 ++++++++-------- ...TwoPassScanningGeneratedAspire.verified.ts | 20 ++++---- .../WithDataVolumeOptionsMerged.verified.ts | 2 +- 7 files changed, 103 insertions(+), 74 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 7fe13af7ff2..c34ae01ca11 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -749,7 +749,12 @@ private static TypeScriptApiItem BuildInterfaceItem( /// Matches the name a declaration fragment declares, for example the RedisResource in /// export interface RedisResource extends ResourceBuilderBase {. /// - [GeneratedRegex(@"^export (?:interface|enum|type) (\w+)", RegexOptions.Multiline)] + /// + /// $ is matched as well as \w because package-qualified options interfaces embed + /// it as the qualifier terminator, and capturing only the qualifier would leave the real name + /// out of the declared set. + /// + [GeneratedRegex(@"^export (?:interface|enum|type) ([\w$]+)", RegexOptions.Multiline)] private static partial Regex DeclaredTypeNameRegex(); private static string BuildInterfaceBody( @@ -1678,7 +1683,7 @@ internal static string ToPascalCase(string name) /// The core hosting package keeps unqualified names even inside a collision group. Other /// packages in those groups carry an encoding of their full assembly name, so /// Aspire.Hosting.Azure.EventHubs yields - /// Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions. The TypeScript + /// Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions. The TypeScript /// API compatibility path guards this selective list so a new cross-package collision cannot /// silently preserve an unsafe unqualified name. /// @@ -1693,7 +1698,13 @@ internal static string GetOptionsInterfaceName(string methodName, string owningA return unqualifiedName; } - return $"{GetOptionsInterfaceQualifier(owningAssemblyName)}{unqualifiedName}"; + // '$' terminates the qualifier. Concatenating two individually injective encodings is not + // injective at the seam -- assembly `Contoso` with method `fooBar` and assembly `ContosoFoo` + // with method `bar` both yield ContosoFooBarOptions -- and the collision guard only inspects + // unqualified names, so two package exports could contribute conflicting declarations under + // one symbol. Every non-alphanumeric code unit in the qualifier is escaped, so '$' can never + // occur inside it: the first '$' is always the seam, whatever the method name contains. + return $"{GetOptionsInterfaceQualifier(owningAssemblyName)}{OptionsInterfaceQualifierSeparator}{unqualifiedName}"; } /// @@ -1717,6 +1728,8 @@ internal static string GetOptionsInterfaceName(string methodName, string owningA /// identifiers may not start with one. /// /// + private const string OptionsInterfaceQualifierSeparator = "$"; + private static string GetOptionsInterfaceQualifier(string owningAssemblyName) { if (string.IsNullOrEmpty(owningAssemblyName) || diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index d87375f23b4..a40cc8e2782 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1819,7 +1819,7 @@ public async Task Generate_SameMethodNameOnDifferentTypes_MergesOptionsInterface // Extract just the merged options interface for snapshot verification. The fixture's // withDataVolume overloads are owned by the test assembly, so they merge into that // assembly's interface rather than into the core one of the same base name. - var interfaceName = $"{TestOptionsPrefix}WithDataVolumeOptions"; + var interfaceName = $"{TestOptionsPrefix}$WithDataVolumeOptions"; var interfaceStart = code.IndexOf($"export interface {interfaceName}", StringComparison.Ordinal); Assert.True(interfaceStart >= 0, $"{interfaceName} interface not found in generated code"); @@ -2295,7 +2295,7 @@ private static IEnumerable ExtractReferencedTypeNames(string content) } } - [GeneratedRegex(@"^export (?:interface|enum|type) (\w+)", RegexOptions.Multiline)] + [GeneratedRegex(@"^export (?:interface|enum|type) ([\w$]+)", RegexOptions.Multiline)] private static partial Regex DeclaredNameRegex(); [GeneratedRegex(@"enum \w+ \{[^}]*\}")] @@ -2304,7 +2304,9 @@ private static IEnumerable ExtractReferencedTypeNames(string content) [GeneratedRegex(@"'[^']*'|""[^""]*""")] private static partial Regex StringLiteralRegex(); - [GeneratedRegex(@"\b[A-Z][A-Za-z0-9_]*\b")] + // '$' is part of an identifier, not a boundary: package-qualified options interfaces use it as + // the qualifier terminator, so \b would split one symbol into two undeclared halves. + [GeneratedRegex(@"(? projector.ResolveOptionsInterfaceName( projector.Resolved.Context.Capabilities.Single(c => c.CapabilityId == $"{packageName}/runAsEmulator")); - Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); - Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); + Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); + Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); Assert.Equal( EmulatorInterfaceName(hubsAlone, CollisionPackageA), @@ -2697,8 +2699,22 @@ public void OptionsInterfaceQualifiersDistinguishAssembliesThatDifferOnlyBySepar var joined = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.FooBar"); Assert.NotEqual(dotted, joined); - Assert.Equal("Contoso_x002E_Foo_x002E_BarRunAsEmulatorOptions", dotted); - Assert.Equal("Contoso_x002E_FooBarRunAsEmulatorOptions", joined); + Assert.Equal("Contoso_x002E_Foo_x002E_Bar$RunAsEmulatorOptions", dotted); + Assert.Equal("Contoso_x002E_FooBar$RunAsEmulatorOptions", joined); + } + + /// + /// Two individually injective encodings still alias if they are simply concatenated, so the + /// qualifier has to be terminated. + /// + [Fact] + public void OptionsInterfaceQualifiersDoNotAliasAcrossTheQualifierBoundary() + { + // Contoso + fooBar and ContosoFoo + bar both produce ContosoFooBarOptions without a seam, + // and the collision guard only inspects unqualified names, so nothing would catch it. + Assert.NotEqual( + TypeScriptApiProjector.GetOptionsInterfaceName("fooBar", "Contoso"), + TypeScriptApiProjector.GetOptionsInterfaceName("bar", "ContosoFoo")); } /// @@ -2732,7 +2748,7 @@ public void OptionsInterfaceQualifiersEscapeAssemblyNamesThatStartWithADigit() { var name = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "3rdParty.Aspire"); - Assert.Equal("_x0033_rdParty_x002E_AspireRunAsEmulatorOptions", name); + Assert.Equal("_x0033_rdParty_x002E_Aspire$RunAsEmulatorOptions", name); Assert.True(name[0] is '_' or '$' || char.IsLetter(name[0]), $"'{name}' is not a valid TypeScript identifier."); Assert.NotEqual(name, TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "_3rdParty.Aspire")); } @@ -2748,9 +2764,9 @@ public void OptionsInterfaceQualifiersUseTheFullAssemblyName() var aspireRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Aspire.Redis"); var bareRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Redis"); - Assert.Equal("Aspire_x002E_Hosting_x002E_RedisRunAsEmulatorOptions", hostingRedis); - Assert.Equal("Aspire_x002E_RedisRunAsEmulatorOptions", aspireRedis); - Assert.Equal("RedisRunAsEmulatorOptions", bareRedis); + Assert.Equal("Aspire_x002E_Hosting_x002E_Redis$RunAsEmulatorOptions", hostingRedis); + Assert.Equal("Aspire_x002E_Redis$RunAsEmulatorOptions", aspireRedis); + Assert.Equal("Redis$RunAsEmulatorOptions", bareRedis); Assert.Equal(3, new[] { hostingRedis, aspireRedis, bareRedis }.Distinct(StringComparer.Ordinal).Count()); } @@ -2767,7 +2783,7 @@ public void ThirdPartyOptionsInterfaceNamesAreQualifiedEvenWhenTheNameIsUniqueIn { var name = TypeScriptApiProjector.GetOptionsInterfaceName("withDescription", "Contoso.Aspire.Hosting.Widgets"); - Assert.Equal("Contoso_x002E_Aspire_x002E_Hosting_x002E_WidgetsWithDescriptionOptions", name); + Assert.Equal("Contoso_x002E_Aspire_x002E_Hosting_x002E_Widgets$WithDescriptionOptions", name); } /// @@ -2798,15 +2814,15 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() documentedOptions, item => { - Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions", item.Name); + Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions", item.Name); Assert.Equal(CollisionPackageA, item.OwningAssemblyName); }); var serviceBusDeclaration = Assert.Single( model.Declarations, - declaration => declaration.Content.Contains("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions", StringComparison.Ordinal)); + declaration => declaration.Content.Contains("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions", StringComparison.Ordinal)); - Assert.Equal($"{CollisionPackageB}:options:Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions", serviceBusDeclaration.Id); + Assert.Equal($"{CollisionPackageB}:options:Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions", serviceBusDeclaration.Id); Assert.Equal(CollisionPackageB, serviceBusDeclaration.OwningAssemblyName); } @@ -2835,8 +2851,8 @@ public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() /// /// [Theory] - [InlineData(CollisionPackageA, "Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubsRunAsEmulatorOptions")] - [InlineData(CollisionPackageB, "Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBusRunAsEmulatorOptions")] + [InlineData(CollisionPackageA, "Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions")] + [InlineData(CollisionPackageB, "Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions")] public void ApiExportNamesACollidingOptionsInterfaceTheWayGenerationDoes(string packageName, string expectedInterfaceName) { var fullContext = CreateEmulatorCollisionContext(); diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts index 13ee4ae62db..bea3f6e9feb 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts @@ -180,12 +180,12 @@ export interface AddTestRedisOptions { port?: number; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions { mode?: TestPersistenceMode; } @@ -807,7 +807,7 @@ export interface TestDatabaseResource { * Adds a data volume * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestDatabaseResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestDatabaseResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestDatabaseResourcePromise; /** Adds a categorized label to the resource */ @@ -875,7 +875,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withCancellableOperation(operation)), this._client); } - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestDatabaseResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -1476,7 +1476,7 @@ export interface TestRedisResource { * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -1543,7 +1543,7 @@ export interface TestRedisResource { * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1581,7 +1581,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -1648,7 +1648,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1720,7 +1720,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -2137,7 +2137,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -2300,7 +2300,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } @@ -2404,7 +2404,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt index d4a35dbc5da..181d7974e2f 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt @@ -659,7 +659,7 @@ export interface TestMutableCollectionContext { export interface TestRedisResource extends ResourceBuilderBase { toJSON(): MarshalledHandle; addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; withConfig(config: TestConfigDto): TestRedisResourcePromise; getTags(): Promise>; @@ -685,7 +685,7 @@ export interface TestRedisResource extends ResourceBuilderBase { withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; @@ -699,7 +699,7 @@ export interface TestRedisResource extends ResourceBuilderBase { // Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise export interface TestRedisResourcePromise extends PromiseLike { addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; withConfig(config: TestConfigDto): TestRedisResourcePromise; getTags(): Promise>; @@ -725,7 +725,7 @@ export interface TestRedisResourcePromise extends PromiseLike withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; withMergeLabel(label: string): TestRedisResourcePromise; withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; @@ -824,14 +824,14 @@ export interface AddTestRedisOptions { port?: number; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { +// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions { mode?: TestPersistenceMode; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json index 998230f9b67..9bebfef2df9 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json @@ -5018,14 +5018,14 @@ "id": "method:TestRedisResource.withPersistence", "kind": "method", "name": "withPersistence", - "declaration": "withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise", + "declaration": "withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withPersistence", "returnType": "TestRedisResourcePromise", "summary": "Configures the Redis resource with persistence", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", "optional": true } ] @@ -5418,14 +5418,14 @@ "id": "method:TestRedisResource.withDataVolume", "kind": "method", "name": "withDataVolume", - "declaration": "withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise", + "declaration": "withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise", "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDataVolume", "returnType": "TestRedisResourcePromise", "summary": "Adds a data volume with persistence", "parameters": [ { "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", "optional": true } ] @@ -6205,21 +6205,21 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.name", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions.name", "kind": "property", "name": "name", "declaration": "name?: string" }, { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions.isReadOnly", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions.isReadOnly", "kind": "property", "name": "isReadOnly", "declaration": "isReadOnly?: boolean" @@ -6227,15 +6227,15 @@ ] }, { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", + "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", "members": [ { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions.mode", + "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions.mode", "kind": "property", "name": "mode", "declaration": "mode?: TestPersistenceMode" @@ -6548,12 +6548,12 @@ { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" + "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", @@ -6586,14 +6586,14 @@ "content": "export interface AddTestRedisOptions {\n port?: number;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" }, { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions", + "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" + "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" }, { "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions", diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts index be68910f2e3..15073dfea24 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts @@ -1538,12 +1538,12 @@ export interface ArgOptions { defaultValue?: string; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { name?: string; isReadOnly?: boolean; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions { mode?: TestPersistenceMode; } @@ -47378,7 +47378,7 @@ export interface TestRedisResource { * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -47445,7 +47445,7 @@ export interface TestRedisResource { * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -48251,7 +48251,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -48318,7 +48318,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -50765,7 +50765,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -51182,7 +51182,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -51721,7 +51721,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } @@ -51825,7 +51825,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts index f326f9e80a2..8bd1a447733 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts @@ -1,4 +1,4 @@ -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_TestsWithDataVolumeOptions { +export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { name?: string; isReadOnly?: boolean; } \ No newline at end of file From 5d95348cbbc985e5bf436d9ed591f93ff21ca5f1 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 21:04:11 -0400 Subject: [PATCH 48/73] Qualify the two colliding options interface names The collision guard reports WithHostPortOptions across eleven packages and AddSecretOptions across Azure.KeyVault and Docker. Both are real: the generator builds an options interface from every optional-or-nullable parameter, and it names it from the projected method, so Docker's addComposeFileSecret and KeyVault's addSecret both emit AddSecretOptions. Apply the documented remedy and package-qualify both names. The synthetic guard test moves to withProbePort, since a name on the qualified list is qualified and therefore cannot collide. --- .../CodeGeneration/TypeScriptOptionsInterfaceNaming.cs | 2 ++ .../TypeScriptApiCompat/TypeScriptApiCompatTests.cs | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs b/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs index 3ef0e5c2f6c..b876aee32b6 100644 --- a/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs +++ b/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs @@ -19,6 +19,7 @@ internal static class TypeScriptOptionsInterfaceNaming "AddCertManagerOptions", "AddDatabaseOptions", "AddHubOptions", + "AddSecretOptions", "RunAsContainerOptions", "RunAsEmulatorOptions", "WithAccessKeyAuthenticationOptions", @@ -26,6 +27,7 @@ internal static class TypeScriptOptionsInterfaceNaming "WithDataBindMountOptions", "WithDataVolumeOptions", "WithForwardedHeadersOptions", + "WithHostPortOptions", "WithHttpsUpgradeOptions", "WithOtlpExporterOptions", "WithPersistenceOptions", diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index 978431dc5ce..ee4a846e19e 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -460,16 +460,18 @@ public void RunnerFailsWhenAliasedCapabilitiesProjectToTheSameOptionsInterface() // Both packages alias distinct capability ids onto the same projected method, which is what // [AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] does. The ids do - // not collide; the generated WithHostPortOptions interfaces do. + // not collide; the generated WithProbePortOptions interfaces do. The projected name is + // deliberately absent from PackageQualifiedOptionsInterfaceNames, because a name on that + // list is qualified and so cannot collide. foreach (var root in new[] { baselineRoot, currentRoot }) { WriteSurface(root, "Pkg.One", """ # Capabilities - Pkg.One/withCommanderHostPort(port?: number) -> void [method=withHostPort] + Pkg.One/withCommanderProbePort(port?: number) -> void [method=withProbePort] """); WriteSurface(root, "Pkg.Two", """ # Capabilities - Pkg.Two/withInsightHostPort(port?: number) -> void [method=withHostPort] + Pkg.Two/withInsightProbePort(port?: number) -> void [method=withProbePort] """); } @@ -489,7 +491,7 @@ public void RunnerFailsWhenAliasedCapabilitiesProjectToTheSameOptionsInterface() Assert.Equal(2, exitCode); var message = error.ToString(); - Assert.Contains("WithHostPortOptions", message, StringComparison.Ordinal); + Assert.Contains("WithProbePortOptions", message, StringComparison.Ordinal); Assert.Contains("'Pkg.One'", message, StringComparison.Ordinal); Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); } From 3e136763ca603988f764de9bad0e2b7c3c2fd84a Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 21:36:51 -0400 Subject: [PATCH 49/73] Accept four-segment NuGet package versions NuGet allows a fourth Revision segment that semantic versioning cannot express, so the semver-only argument parse rejected real shipping versions such as Aspire.Hosting.Redis@5.2.9.0 with "floating and range versions are not supported" -- a message that is doubly wrong, since the version is neither. Rather than take a NuGet.Versioning dependency on the Native-AOT CLI for one shape, the four-segment case is normalized directly following NuGet's rules: a zero revision is dropped, a non-zero one is kept, leading zeros are stripped, and pre-release/build-metadata suffixes pass through. Floating and range syntax still fails, because '*', '[' and ',' are not digits. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkCommandPreparation.cs | 75 ++++++++++++++++--- .../Commands/SdkDumpCommandTests.cs | 43 +++++++++++ 2 files changed, 109 insertions(+), 9 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs index 698061bae2f..40bf6f2bd42 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Globalization; using Aspire.Cli.Configuration; using Aspire.Cli.Interaction; using Aspire.Cli.Projects; @@ -78,7 +79,26 @@ public static bool TryParseIntegrationArgument( return false; } - if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out var parsedVersion)) + if (SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out var parsedVersion)) + { + if (requireExactVersion) + { + // SemVersionStyles.Any accepts abbreviated and decorated forms -- "2.0", "v2.0.0", + // "2.01.0" -- that NuGet normalizes on restore. A caller who asks for Package@2.0 gets + // the 2.0.0 package, so recording the raw text would label the export with a version no + // feed serves. Callers that require an exact version get the normalized string, which is + // the one NuGet resolved. + packageVersion = parsedVersion.ToString(); + } + } + else if (TryNormalizeFourSegmentVersion(packageVersion, out var normalizedFourSegmentVersion)) + { + if (requireExactVersion) + { + packageVersion = normalizedFourSegmentVersion; + } + } + else { errorMessage = requireExactVersion ? $"Invalid version '{packageVersion}' in '{argument}'. Expected an exact NuGet version (e.g. 9.2.0); floating and range versions are not supported." @@ -86,17 +106,54 @@ public static bool TryParseIntegrationArgument( return false; } - if (requireExactVersion) + reference = IntegrationReference.FromPackage(packageName, packageVersion); + return true; + } + + /// + /// Normalizes a four-segment NuGet version, which semantic versioning cannot represent. + /// + /// + /// NuGet accepts a fourth Revision segment that semver has no room for, so + /// SemVersion.TryParse rejects real + /// package versions such as 5.2.9.0 and 1.2.3.4-beta. Only that shape is handled + /// here, and it follows NuGet's own normalization: a zero revision is dropped + /// (1.2.3.0 becomes 1.2.3) while a non-zero one is kept, leading zeros are + /// stripped, and the pre-release and build-metadata suffixes are carried through untouched. + /// Floating and range syntax still fails, because *, [, and , are not + /// digits. See https://learn.microsoft.com/nuget/concepts/package-versioning. + /// + private static bool TryNormalizeFourSegmentVersion(string version, out string normalized) + { + normalized = string.Empty; + + // The suffix starts at whichever of '-' or '+' comes first, so "1.2.3.4-beta+sha" keeps + // "-beta+sha" and "1.2.3.4+sha" keeps "+sha". + var suffixIndex = version.AsSpan().IndexOfAny('-', '+'); + var numericPart = suffixIndex < 0 ? version : version[..suffixIndex]; + var suffix = suffixIndex < 0 ? string.Empty : version[suffixIndex..]; + + var segments = numericPart.Split('.'); + if (segments.Length != 4) + { + return false; + } + + var parsedSegments = new int[4]; + for (var i = 0; i < segments.Length; i++) { - // SemVersionStyles.Any accepts abbreviated and decorated forms -- "2.0", "v2.0.0", - // "2.01.0" -- that NuGet normalizes on restore. A caller who asks for Package@2.0 gets - // the 2.0.0 package, so recording the raw text would label the export with a version no - // feed serves. Callers that require an exact version get the normalized string, which is - // the one NuGet resolved. - packageVersion = parsedVersion.ToString(); + // NumberStyles.None rejects signs, whitespace, and thousands separators, so only a bare + // run of digits gets through. + if (!int.TryParse(segments[i], NumberStyles.None, CultureInfo.InvariantCulture, out parsedSegments[i])) + { + return false; + } } - reference = IntegrationReference.FromPackage(packageName, packageVersion); + normalized = parsedSegments[3] == 0 + ? $"{parsedSegments[0]}.{parsedSegments[1]}.{parsedSegments[2]}{suffix}" + : $"{parsedSegments[0]}.{parsedSegments[1]}.{parsedSegments[2]}.{parsedSegments[3]}{suffix}"; + return true; } diff --git a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs index d1d8b65efbb..a194b5155bc 100644 --- a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs @@ -443,6 +443,49 @@ public void SdkDumpRecordsTheRequestedPackageVersionRatherThanTheResolvedOne() Assert.Equal("13.4.0", package.GetProperty("Version").GetString()); } + /// + /// NuGet package versions may carry a fourth Revision segment that semantic versioning + /// cannot express, so a semver-only parse would reject shipping packages such as + /// 5.2.9.0. Argument parsing has to accept them and normalize the way NuGet does. + /// + [Theory] + [InlineData("5.2.9.0", "5.2.9")] + [InlineData("1.2.3.4", "1.2.3.4")] + [InlineData("1.2.3.4-beta.1", "1.2.3.4-beta.1")] + [InlineData("01.02.03.00", "1.2.3")] + public void FourSegmentPackageVersionsAreAcceptedAndNormalizedLikeNuGet(string requested, string expected) + { + Assert.True(SdkCommandPreparation.TryParseIntegrationArgument( + $"Aspire.Hosting.Redis@{requested}", + requireExactVersion: true, + out var reference, + out _, + out var errorMessage), errorMessage); + + Assert.Equal(expected, reference!.Version); + } + + /// + /// Accepting a fourth segment must not open the door to the floating and range syntax that + /// sdk export deliberately refuses, since neither pins a single document version. + /// + [Theory] + [InlineData("1.2.3.*")] + [InlineData("[1.0.0.0,2.0.0.0)")] + [InlineData("1.2.3.4.5")] + [InlineData("1.2.3.-1")] + public void FloatingAndRangeVersionsAreStillRejected(string requested) + { + Assert.False(SdkCommandPreparation.TryParseIntegrationArgument( + $"Aspire.Hosting.Redis@{requested}", + requireExactVersion: true, + out _, + out _, + out var errorMessage)); + + Assert.Contains($"Invalid version '{requested}'", errorMessage); + } + /// /// The checked-in *.ats.txt baselines are produced with --format ci, which carries /// no package versions at all. That is what keeps the requested-version semantics above from From 6f23cbd06995f6fa7151799b7f7f76db74ad95fb Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 21:43:23 -0400 Subject: [PATCH 50/73] Put the opening brace on its own line Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../CodeGenerationResolverTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs index fb3eefb03d0..83e720d599d 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGenerationResolverTests.cs @@ -74,7 +74,8 @@ public void CodeGeneratorResolver_DoesNotResolveAnExporterForALanguageWithNoGene } [Fact] - public void LanguageSupportResolver_DiscoversInternalLanguageSupports() { + public void LanguageSupportResolver_DiscoversInternalLanguageSupports() + { using var serviceProvider = CreateServiceProvider(); var assemblyLoader = CreateAssemblyLoader(); var resolver = new LanguageSupportResolver(serviceProvider, assemblyLoader, NullLogger.Instance); From 2e1a9dbc9f0ef98bdbfb1bcdb3287d4630229814 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 21:52:27 -0400 Subject: [PATCH 51/73] Pin the two shipped options interface collisions AddSecretOptions and WithHostPortOptions are on the package-qualified list because the shipped surface really does collide on them: Docker's addComposeFileSecret projects as addSecret next to Key Vault's addSecret, and eleven packages project withHostPort. Nothing failed if either entry were dropped again -- the existing aliased-collision test uses a synthetic name that is deliberately off the list -- so add a test that replays the real colliding capabilities and requires the guard to stay quiet. Removing either entry fails it with the same "Unqualified TypeScript options interface collision detected" text CI reported. Also move OptionsInterfaceQualifierSeparator above the doc comment it was inserted into, so the block reattaches to GetOptionsInterfaceQualifier. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../TypeScriptApiProjector.cs | 4 +- .../TypeScriptApiCompatTests.cs | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index c34ae01ca11..e0ca0083491 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -1707,6 +1707,8 @@ internal static string GetOptionsInterfaceName(string methodName, string owningA return $"{GetOptionsInterfaceQualifier(owningAssemblyName)}{OptionsInterfaceQualifierSeparator}{unqualifiedName}"; } + private const string OptionsInterfaceQualifierSeparator = "$"; + /// /// Derives the name-space prefix an assembly's options interfaces carry when their unqualified /// names are in a known collision group. @@ -1728,8 +1730,6 @@ internal static string GetOptionsInterfaceName(string methodName, string owningA /// identifiers may not start with one. /// /// - private const string OptionsInterfaceQualifierSeparator = "$"; - private static string GetOptionsInterfaceQualifier(string owningAssemblyName) { if (string.IsNullOrEmpty(owningAssemblyName) || diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index ee4a846e19e..6f38b509abb 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -496,6 +496,65 @@ public void RunnerFailsWhenAliasedCapabilitiesProjectToTheSameOptionsInterface() Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); } + /// + /// The shipped surface really does produce the two collisions that only became visible once the + /// guard started naming the interface after the projected method: Docker's + /// addComposeFileSecret projects as addSecret next to Key Vault's addSecret, + /// and eleven packages project withHostPort. Both unqualified names are in + /// PackageQualifiedOptionsInterfaceNames, so those packages emit package-qualified + /// interfaces and the guard has to stay quiet. Dropping either entry puts a conflicting + /// unqualified declaration back into the concatenated package exports, which is the exact + /// failure this repository shipped to CI before those entries were added. + /// + [Fact] + public void RunnerAllowsShippedAliasCollisionsThatPackageQualifiedNamesAlreadyResolve() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + var baselineRoot = Path.Combine(workspace.Path, "baseline"); + var currentRoot = Path.Combine(workspace.Path, "current"); + + // Trimmed from the surfaces `aspire sdk dump --format ci` actually emits for these packages. + foreach (var root in new[] { baselineRoot, currentRoot }) + { + WriteSurface(root, "Aspire.Hosting.Azure.KeyVault", """ + # Capabilities + Aspire.Hosting.Azure.KeyVault/addSecret(name: string, value?: string) -> void + """); + WriteSurface(root, "Aspire.Hosting.Docker", """ + # Capabilities + Aspire.Hosting.Docker/addComposeFileSecret(name: string, value?: string) -> void [method=addSecret] + Aspire.Hosting.Docker/withHostPort(port?: number) -> void + """); + WriteSurface(root, "Aspire.Hosting.Redis", """ + # Capabilities + Aspire.Hosting.Redis/withHostPort(port?: number) -> void + Aspire.Hosting.Redis/withRedisCommanderHostPort(port?: number) -> void [method=withHostPort] + """); + WriteSurface(root, "Aspire.Hosting.PostgreSQL", """ + # Capabilities + Aspire.Hosting.PostgreSQL/withPgAdminHostPort(port?: number) -> void [method=withHostPort] + """); + } + + using var error = new StringWriter(); + + var exitCode = TypeScriptApiCompatRunner.Run( + new CommandLineOptions( + baselineRoot, + currentRoot, + workspace.Path, + BaselineSuppressionsRoot: null, + ExcludedPackagesFile: null, + ReportPath: null, + GitHubAnnotations: false), + error); + + // Assert the guard output before the exit code so a regression reports the collision text + // instead of just "expected 0, actual 2". + Assert.Equal(string.Empty, error.ToString()); + Assert.Equal(0, exitCode); + } + [Fact] public void RunnerAllowsSharedCapabilityIdsThatProjectToDifferentMethodNames() { From bc0d1c5ed367dfb2aa14d20ceee02056ca8d9ee2 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Sun, 9 Aug 2026 22:18:43 -0400 Subject: [PATCH 52/73] Validate the suffix on a four-segment version The four-segment path checked only the numeric prefix and copied whatever followed, so "1.2.3.4-" and "1.2.3.4-beta_1" reached restore instead of the invalid-version error. Handing the semver-shaped equivalent back to the parser validates the pre-release and build-metadata grammar without reimplementing it. SemVersionStyles.Any keeps the leading zeros in labels that NuGet accepts and semver does not. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Commands/Sdk/SdkCommandPreparation.cs | 13 ++++++++++++- .../Commands/SdkDumpCommandTests.cs | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs index 40bf6f2bd42..95c393a2a83 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs @@ -150,8 +150,19 @@ private static bool TryNormalizeFourSegmentVersion(string version, out string no } } + // Only the numeric prefix has been checked so far, so "1.2.3.4-" and "1.2.3.4+sha space" + // would still get through. Handing the semver-shaped equivalent back to the parser validates + // the pre-release and build-metadata grammar without reimplementing it. SemVersionStyles.Any + // is deliberate: it allows the leading zeros in labels that NuGet accepts and semver does not + // ("1.2.3-beta.01"), while still rejecting an empty or malformed label. + var semanticEquivalent = $"{parsedSegments[0]}.{parsedSegments[1]}.{parsedSegments[2]}{suffix}"; + if (!SemVersion.TryParse(semanticEquivalent, SemVersionStyles.Any, out _)) + { + return false; + } + normalized = parsedSegments[3] == 0 - ? $"{parsedSegments[0]}.{parsedSegments[1]}.{parsedSegments[2]}{suffix}" + ? semanticEquivalent : $"{parsedSegments[0]}.{parsedSegments[1]}.{parsedSegments[2]}.{parsedSegments[3]}{suffix}"; return true; diff --git a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs index a194b5155bc..b4e6d5c6432 100644 --- a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs @@ -453,6 +453,8 @@ public void SdkDumpRecordsTheRequestedPackageVersionRatherThanTheResolvedOne() [InlineData("1.2.3.4", "1.2.3.4")] [InlineData("1.2.3.4-beta.1", "1.2.3.4-beta.1")] [InlineData("01.02.03.00", "1.2.3")] + [InlineData("1.2.3.4-beta.01", "1.2.3.4-beta.01")] + [InlineData("1.2.3.0+sha.abc", "1.2.3+sha.abc")] public void FourSegmentPackageVersionsAreAcceptedAndNormalizedLikeNuGet(string requested, string expected) { Assert.True(SdkCommandPreparation.TryParseIntegrationArgument( @@ -474,6 +476,10 @@ public void FourSegmentPackageVersionsAreAcceptedAndNormalizedLikeNuGet(string r [InlineData("[1.0.0.0,2.0.0.0)")] [InlineData("1.2.3.4.5")] [InlineData("1.2.3.-1")] + [InlineData("1.2.3.4-")] + [InlineData("1.2.3.4+")] + [InlineData("1.2.3.4-.")] + [InlineData("1.2.3.4-beta_1")] public void FloatingAndRangeVersionsAreStillRejected(string requested) { Assert.False(SdkCommandPreparation.TryParseIntegrationArgument( From 5563e7ce6c8a8e2faf27e6f42103b0706f470e6c Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 00:03:22 -0400 Subject: [PATCH 53/73] Keep the generator path off the new AtsContext member The exporter split protects type loading, not method bodies. Reading AtsContext.CapabilityExportingAssemblyNames straight from the projector hard-bound the generation path to a contract member a shipped CLI does not have, so building the projector threw MissingMethodException and took ordinary TypeScript generation down with it. Route the read through a probe that answers "absent" instead of throwing, and pin the invariant with an IL-level test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../AtsContextCompatibility.cs | 77 +++++ .../AtsTypeScriptApiReferenceExporter.cs | 6 + .../TypeScriptApiProjector.cs | 9 +- ...ing.CodeGeneration.TypeScript.Tests.csproj | 6 + .../PriorContractBindingTests.cs | 291 ++++++++++++++++++ 5 files changed, 387 insertions(+), 2 deletions(-) create mode 100644 src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs create mode 100644 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs new file mode 100644 index 00000000000..57e0a6d03d8 --- /dev/null +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using Aspire.TypeSystem; + +namespace Aspire.Hosting.CodeGeneration.TypeScript; + +/// +/// Reads members that were added after the shared contract's frozen +/// strong-name version, in a way that degrades instead of failing when the loaded contract predates +/// them. +/// +/// +/// +/// Aspire.TypeSystem is force-shared from the apphost server's default +/// and freezes its AssemblyVersion at +/// 13.4.5.0 (see src/Aspire.TypeSystem/Aspire.TypeSystem.csproj and +/// src/Aspire.Hosting.RemoteHost/IntegrationLoadContext.cs), so an already-shipped CLI binds +/// a newer SDK's code generation assembly against its own older copy of the contract. Binding +/// succeeds; the newer members simply are not there. +/// +/// +/// Splitting export onto only protects type +/// loading — a type whose interface list or signatures name a missing type is dropped, and the code +/// generator survives. It does nothing for a method body that names a missing member: the +/// JIT resolves a method's tokens when that method first runs, so a direct read of a newer property +/// from the generator path throws at generation time and takes +/// ordinary TypeScript generation down with it. Probing once and keeping every direct read behind +/// that probe, in a method the JIT is not allowed to inline into its caller, is what keeps the +/// generator path free of that hard bind. +/// +/// +internal static class AtsContextCompatibility +{ + // nameof is a compile-time constant, so the probe itself carries no reference to the member and + // is safe to evaluate against a contract that predates it. + private static readonly bool s_exposesCapabilityExportingAssemblyNames = + typeof(AtsContext).GetProperty(nameof(AtsContext.CapabilityExportingAssemblyNames)) is not null; + + /// + /// Gets the assembly that exported , when the loaded contract + /// records exporting assemblies at all. + /// + /// The ATS context to read. + /// The capability whose exporting assembly is wanted. + /// The exporting assembly name, when one was recorded. + /// + /// when the loaded contract exposes the mapping and it names + /// ; otherwise , which callers are + /// expected to answer with their own ownership fallback. + /// + public static bool TryGetCapabilityExportingAssemblyName( + AtsContext context, + string capabilityId, + [NotNullWhen(true)] out string? exportingAssemblyName) + { + if (s_exposesCapabilityExportingAssemblyNames) + { + return ReadCapabilityExportingAssemblyName(context, capabilityId, out exportingAssemblyName); + } + + exportingAssemblyName = null; + return false; + } + + // NoInlining is load-bearing, not a hint: inlining this body into its caller would move the + // member reference back onto a method the generator path always runs, which is exactly the hard + // bind the probe exists to avoid. + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ReadCapabilityExportingAssemblyName( + AtsContext context, + string capabilityId, + [NotNullWhen(true)] out string? exportingAssemblyName) + => context.CapabilityExportingAssemblyNames.TryGetValue(capabilityId, out exportingAssemblyName); +} diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs index d604b091873..43b4ea34cd6 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs @@ -30,6 +30,12 @@ namespace Aspire.Hosting.CodeGeneration.TypeScript; /// , so the generator survives and only /// this type disappears. /// +/// +/// The split covers type loading only. A method body on the generation path that names a newer +/// shared-contract member is a separate hard bind that no type split can absorb, because +/// the JIT resolves a method's tokens when that method first runs; see +/// for how those reads are kept out of the generator path. +/// /// internal sealed class AtsTypeScriptApiReferenceExporter : IApiReferenceExporter { diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index e0ca0083491..66124d411e6 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -1153,7 +1153,9 @@ private static string GetOwningAssemblyName(string atsId, string? clrAssemblyNam /// /// /// This mirrors AtsContextFilter.IsCapabilityOwnedBySelectedAssembly. The two must agree, - /// or the exporter would document symbols the filter excluded, or drop symbols it kept. + /// or the exporter would document symbols the filter excluded, or drop symbols it kept. A CLI + /// that predates runs the pre-map + /// filter as well, so both sides fall back to reflection together and still agree. /// private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) => GetCapabilityOwningAssemblyName(_resolved.Context, capability); @@ -1165,7 +1167,10 @@ private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) /// private static string GetCapabilityOwningAssemblyName(AtsContext context, AtsCapabilityInfo capability) { - if (context.CapabilityExportingAssemblyNames.TryGetValue(capability.CapabilityId, out var exportingAssemblyName)) + // Read through the compatibility shim rather than off the context directly: this method runs + // on the ordinary generation path, and a direct read hard-binds it to a contract member an + // already-shipped CLI does not have. See AtsContextCompatibility for the failure it avoids. + if (AtsContextCompatibility.TryGetCapabilityExportingAssemblyName(context, capability.CapabilityId, out var exportingAssemblyName)) { return exportingAssemblyName; } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj index 6dfc6bf2fd3..464206d0208 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj @@ -22,6 +22,12 @@ + + + + + diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs new file mode 100644 index 00000000000..b264cbd2f16 --- /dev/null +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs @@ -0,0 +1,291 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Reflection; +using System.Reflection.Emit; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Reflection.PortableExecutable; +using System.Text.RegularExpressions; +using Aspire.TypeSystem; + +namespace Aspire.Hosting.CodeGeneration.TypeScript.Tests; + +/// +/// Guards the one compatibility property that keeps TypeScript generation working on a CLI older +/// than the SDK package that carries this generator. +/// +/// +/// +/// Aspire.TypeSystem is force-shared from the apphost server's default load context and +/// freezes its AssemblyVersion at 13.4.5.0, so an already-shipped CLI binds a newer +/// SDK's Aspire.Hosting.CodeGeneration.TypeScript against the CLI's own, older copy of the +/// contract. Anything this assembly names that the older copy lacks fails at run time, and where it +/// fails depends on where it is named: a missing type in a type's interface list or signatures drops +/// only that type (CodeGeneratorResolver salvages the rest), while a missing member in a +/// method body throws when the JIT compiles that method — which +/// on the generation path means TypeScript generation stops working, not just export. +/// +/// +/// The checked-in src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs reference surface is the +/// repository's record of what has shipped, so it is used here as the definition of "members an +/// already-shipped CLI is guaranteed to have". +/// +/// +public partial class PriorContractBindingTests +{ + /// + /// Types allowed to name post-baseline Aspire.TypeSystem API, and why. + /// + private static readonly Dictionary s_allowedTypes = new(StringComparer.Ordinal) + { + [nameof(AtsTypeScriptApiReferenceExporter)] = + "export lives on its own type precisely so an older CLI drops this type and keeps the code generator", + [nameof(AtsContextCompatibility)] = + "the single guarded read, kept behind a runtime probe in a method the JIT may not inline", + }; + + [Fact] + public void GeneratorPathDoesNotBindTypeSystemMembersOutsideTheShippedBaseline() + { + var shippedNames = ReadShippedTypeSystemIdentifiers(); + + var offenders = GetTypeSystemMemberReferencesByDeclaringType() + .SelectMany(entry => entry.Value.Select(reference => (Type: entry.Key, Reference: reference))) + .Where(candidate => !s_allowedTypes.ContainsKey(candidate.Type)) + .Where(candidate => IsPostBaseline(candidate.Reference, shippedNames)) + .Select(candidate => $"{candidate.Type} -> {candidate.Reference.DeclaringType}.{candidate.Reference.MemberName}") + .Order(StringComparer.Ordinal) + .ToArray(); + + Assert.Empty(offenders); + } + + [Fact] + public void CompatibilityShimKeepsThePostBaselineReadOutOfLine() + { + // Inlining the read into its caller would put the member reference back on a method the + // generation path always runs, undoing the probe. + var read = typeof(AtsContextCompatibility).GetMethod( + "ReadCapabilityExportingAssemblyName", + BindingFlags.NonPublic | BindingFlags.Static); + + Assert.NotNull(read); + Assert.Equal(MethodImplAttributes.NoInlining, read.MethodImplementationFlags & MethodImplAttributes.NoInlining); + } + + [Fact] + public void CompatibilityShimReadsTheMapWhenTheLoadedContractHasIt() + { + // The tests run against the in-repo contract, which does expose the map, so this pins that + // the probe has not degraded the current-CLI path into the fallback. + var context = new AtsContext + { + Capabilities = [], + HandleTypes = [], + DtoTypes = [], + EnumTypes = [], + CapabilityExportingAssemblyNames = new Dictionary(StringComparer.Ordinal) + { + ["Contoso.Widgets/addWidget"] = "Contoso.Widgets.Hosting" + } + }; + + Assert.True(AtsContextCompatibility.TryGetCapabilityExportingAssemblyName(context, "Contoso.Widgets/addWidget", out var owner)); + Assert.Equal("Contoso.Widgets.Hosting", owner); + + Assert.False(AtsContextCompatibility.TryGetCapabilityExportingAssemblyName(context, "Contoso.Widgets/addOther", out var missing)); + Assert.Null(missing); + } + + private static bool IsPostBaseline(TypeSystemMemberReference reference, HashSet shippedNames) + { + if (!shippedNames.Contains(reference.DeclaringType)) + { + return true; + } + + // Accessors carry the property name the baseline declares; constructors have no name to + // match, and overload-level checking is out of scope for a name-based comparison. + var memberName = reference.MemberName switch + { + ".ctor" or ".cctor" => null, + ['g', 'e', 't', '_', .. var property] => property, + ['s', 'e', 't', '_', .. var property] => property, + var other => other, + }; + + return memberName is not null && !shippedNames.Contains(memberName); + } + + private static HashSet ReadShippedTypeSystemIdentifiers() + { + // Copied next to the test binary by the project file so this works from any working + // directory, including Helix. + var baselinePath = Path.Combine(AppContext.BaseDirectory, "ApiBaseline", "Aspire.TypeSystem.cs"); + Assert.True(File.Exists(baselinePath), $"Missing shipped API baseline at '{baselinePath}'."); + + return IdentifierRegex() + .Matches(File.ReadAllText(baselinePath)) + .Select(match => match.Value) + .ToHashSet(StringComparer.Ordinal); + } + + /// + /// Collects, per declaring type, the Aspire.TypeSystem members that the generator + /// assembly's method bodies name. + /// + /// + /// Method bodies are read rather than reflected over because the question is what the IL binds + /// to, not what the current contract happens to resolve. Nested types (including compiler + /// generated closures) are attributed to their outermost declaring type so a lambda cannot + /// smuggle a reference past the allow-list. + /// + private static Dictionary> GetTypeSystemMemberReferencesByDeclaringType() + { + var assemblyPath = typeof(AtsTypeScriptCodeGenerator).Assembly.Location; + using var stream = File.OpenRead(assemblyPath); + using var peReader = new PEReader(stream); + var reader = peReader.GetMetadataReader(); + + var references = new Dictionary>(StringComparer.Ordinal); + + foreach (var typeHandle in reader.TypeDefinitions) + { + var typeDefinition = reader.GetTypeDefinition(typeHandle); + var owningTypeName = GetOutermostTypeName(reader, typeDefinition); + + foreach (var methodHandle in typeDefinition.GetMethods()) + { + var method = reader.GetMethodDefinition(methodHandle); + if (method.RelativeVirtualAddress == 0) + { + continue; + } + + var il = peReader.GetMethodBody(method.RelativeVirtualAddress).GetILBytes(); + if (il is null) + { + continue; + } + + foreach (var reference in ReadTypeSystemMemberReferences(reader, il)) + { + if (!references.TryGetValue(owningTypeName, out var list)) + { + references[owningTypeName] = list = []; + } + + list.Add(reference); + } + } + } + + return references; + } + + private static IEnumerable ReadTypeSystemMemberReferences(MetadataReader reader, byte[] il) + { + var offset = 0; + while (offset < il.Length) + { + OpCode opCode; + if (il[offset] == 0xFE) + { + if (offset + 1 >= il.Length || s_twoByteOpCodes.Value[il[offset + 1]] is not { } prefixed) + { + yield break; + } + + opCode = prefixed; + offset += 2; + } + else + { + if (s_oneByteOpCodes.Value[il[offset]] is not { } simple) + { + yield break; + } + + opCode = simple; + offset += 1; + } + + var operandSize = GetOperandSize(opCode, il, offset); + if (opCode.OperandType is OperandType.InlineField or OperandType.InlineMethod or OperandType.InlineTok && + MetadataTokens.EntityHandle(BitConverter.ToInt32(il, offset)) is { Kind: HandleKind.MemberReference } handle) + { + var memberReference = reader.GetMemberReference((MemberReferenceHandle)handle); + if (memberReference.Parent.Kind == HandleKind.TypeReference) + { + var parent = (TypeReferenceHandle)memberReference.Parent; + if (GetAssemblyName(reader, parent) == "Aspire.TypeSystem") + { + yield return new TypeSystemMemberReference( + reader.GetString(reader.GetTypeReference(parent).Name), + reader.GetString(memberReference.Name)); + } + } + } + + offset += operandSize; + } + } + + private static int GetOperandSize(OpCode opCode, byte[] il, int operandOffset) => opCode.OperandType switch + { + OperandType.InlineNone => 0, + OperandType.ShortInlineBrTarget or OperandType.ShortInlineI or OperandType.ShortInlineVar => 1, + OperandType.InlineVar => 2, + OperandType.InlineI8 or OperandType.InlineR => 8, + // A switch is a 4-byte case count followed by that many 4-byte targets. + OperandType.InlineSwitch => 4 + (4 * BitConverter.ToInt32(il, operandOffset)), + _ => 4, + }; + + private static string GetOutermostTypeName(MetadataReader reader, TypeDefinition typeDefinition) + { + while (typeDefinition.IsNested) + { + typeDefinition = reader.GetTypeDefinition(typeDefinition.GetDeclaringType()); + } + + return reader.GetString(typeDefinition.Name); + } + + private static string GetAssemblyName(MetadataReader reader, EntityHandle handle) => handle.Kind switch + { + HandleKind.AssemblyReference => reader.GetString(reader.GetAssemblyReference((AssemblyReferenceHandle)handle).Name), + HandleKind.TypeReference => GetAssemblyName(reader, reader.GetTypeReference((TypeReferenceHandle)handle).ResolutionScope), + _ => string.Empty, + }; + + private static readonly Lazy s_oneByteOpCodes = new(() => BuildOpCodeTable(twoByte: false)); + + private static readonly Lazy s_twoByteOpCodes = new(() => BuildOpCodeTable(twoByte: true)); + + private static OpCode?[] BuildOpCodeTable(bool twoByte) + { + var table = new OpCode?[0x100]; + foreach (var field in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) + { + if (field.GetValue(null) is not OpCode opCode) + { + continue; + } + + var value = unchecked((ushort)opCode.Value); + if (twoByte == value >= 0x100) + { + table[value & 0xFF] = opCode; + } + } + + return table; + } + + [GeneratedRegex("[A-Za-z_][A-Za-z0-9_]*")] + private static partial Regex IdentifierRegex(); + + private readonly record struct TypeSystemMemberReference(string DeclaringType, string MemberName); +} From 98991cc0ee3360e958fe816ce908755175c43b8d Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 00:21:35 -0400 Subject: [PATCH 54/73] Add regression coverage for four-segment build metadata in sdk export Copilot review suggested StripBuildMetadata could not reach four-segment versions. It can: the helper is a plain IndexOf(0x2B) truncation applied to reference.Version, so 2.0.0.4+sha already exports as 2.0.0.4. Pin that with a test rather than changing behaviour. --- .../Commands/Sdk/SdkExportCommandTests.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 7d8611aea65..4f0f2000ebd 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -311,6 +311,33 @@ public async Task SdkExportPublishesTheVersionNuGetResolvesRatherThanTheRequeste Assert.Equal("2.0.0", requested.Version); } + /// + /// The four-segment path normalizes separately from the semver one, so it gets the same + /// build-metadata guarantee: NuGet ignores metadata for identity, and the document must be + /// labelled with the version a feed can actually serve. + /// + [Fact] + public async Task SdkExportPublishesAFourSegmentVersionWithoutItsBuildMetadata() + { + var interactionService = new TestInteractionService(); + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); + var rpcClient = new StubExportRpcClient(); + using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0.4+fake"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0.4"), rpcClient.LastExportRequest); + + var requested = Assert.Single( + appHostServerProject.Integrations, + integration => integration.Name == "Contoso.Aspire.Widgets"); + Assert.Equal("2.0.0.4", requested.Version); + } + [Theory] [InlineData("13.5.*")] [InlineData("[13.5.0,14.0.0)")] From fa64fe6f4fcfea2e4ef96c417372aca7e5ac2956 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 16:20:28 -0400 Subject: [PATCH 55/73] Reduce API export to the focused contract Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c235246b-d021-4d8e-b041-cc4984674ebe --- docs/specs/cli-output-formats.md | 6 + src/Aspire.Cli/CliExecutionContext.cs | 17 +- .../Commands/Sdk/SdkCommandPreparation.cs | 335 - src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs | 298 +- .../Commands/Sdk/SdkExportCommand.cs | 545 +- .../Commands/Sdk/SdkGenerateCommand.cs | 7 - .../Configuration/IntegrationReference.cs | 55 - src/Aspire.Cli/Program.cs | 7 - .../Projects/AppHostServerClosureSnapshots.cs | 4 +- .../DotNetBasedAppHostServerProject.cs | 349 +- .../Projects/IAppHostServerProject.cs | 13 - .../Projects/LocalProjectSubstitution.cs | 23 - .../Projects/PrebuiltAppHostServer.cs | 23 +- ...e.Hosting.CodeGeneration.TypeScript.csproj | 1 - .../AtsContextCompatibility.cs | 77 - .../AtsTypeScriptApiReferenceExporter.cs | 14 +- .../TypeScriptApiExportWriter.cs | 8 +- .../TypeScriptApiModel.cs | 10 + .../TypeScriptApiProjector.cs | 181 +- .../Aspire.Hosting.RemoteHost.csproj | 4 - .../AssemblyLoader.cs | 86 +- .../AtsCapabilityScanner.cs | 78 +- .../AtsContextFilter.cs | 44 +- .../CodeGeneration/CodeGenerationService.cs | 61 +- .../RemoteHostProfilingTelemetry.cs | 8 - .../NuGet/Commands/ManifestCommand.cs | 4 +- .../Commands/NuGetPackageAssetResolver.cs | 93 +- src/Aspire.TypeSystem/AtsContext.cs | 11 - .../IApiReferenceExporter.cs | 6 +- .../TypeScriptOptionsInterfaceNaming.cs | 79 - src/Shared/IntegrationPackageProbeManifest.cs | 52 +- .../Commands/Sdk/SdkExportCommandTests.cs | 872 +-- .../Commands/SdkDumpCommandTests.cs | 174 - .../IntegrationReferenceTests.cs | 37 - .../Projects/AppHostServerProjectTests.cs | 23 + ...BasedAppHostServerPackageReferenceTests.cs | 449 -- .../Projects/PrebuiltAppHostServerTests.cs | 152 +- .../FakeSucceedingAppHostServerProject.cs | 28 - .../Utils/OfflineNuGetFeed.cs | 148 - .../Utils/TestExecutionContextHelper.cs | 10 +- ...ing.CodeGeneration.TypeScript.Tests.csproj | 6 - .../AtsTypeScriptCodeGeneratorTests.cs | 1502 +--- .../PriorContractBindingTests.cs | 291 - .../Snapshots/AtsGeneratedAspire.verified.ts | 42 +- ...eneratorTests.ApiDeclarations.verified.txt | 991 --- ...CodeGeneratorTests.ApiExport.verified.json | 6809 ----------------- ...eratorTests.FocusedApiExport.verified.json | 53 + ...TwoPassScanningGeneratedAspire.verified.ts | 34 +- .../WithDataVolumeOptionsMerged.verified.ts | 2 +- .../AssemblyLoaderTests.cs | 45 - .../AtsCapabilityScannerTests.cs | 92 - .../AtsContextFilterTests.cs | 55 - .../CodeGeneration/ApiReferenceExportTests.cs | 69 +- .../LayoutCommandTests.cs | 6 - .../TypeScriptApiCompatTests.cs | 342 +- .../AtsCompatibilityComparer.cs | 26 +- tools/TypeScriptApiCompat/AtsSurface.cs | 25 +- tools/TypeScriptApiCompat/AtsSurfaceParser.cs | 37 +- .../TypeScriptApiCompat.csproj | 4 - .../TypeScriptApiCompatRunner.cs | 14 +- .../TypeScriptOptionsCollisionGuard.cs | 127 - 61 files changed, 1045 insertions(+), 13919 deletions(-) delete mode 100644 src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs delete mode 100644 src/Aspire.Cli/Projects/LocalProjectSubstitution.cs delete mode 100644 src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs delete mode 100644 src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs delete mode 100644 tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs delete mode 100644 tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs delete mode 100644 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs delete mode 100644 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt delete mode 100644 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json create mode 100644 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.FocusedApiExport.verified.json delete mode 100644 tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs diff --git a/docs/specs/cli-output-formats.md b/docs/specs/cli-output-formats.md index bfa2ae3050f..d686df29d6a 100644 --- a/docs/specs/cli-output-formats.md +++ b/docs/specs/cli-output-formats.md @@ -582,3 +582,9 @@ The top-level arrays are: | `diagnostics` | Errors, warnings, and informational diagnostics from capability discovery. | `aspire sdk dump --format ci` emits a stable text format intended for diffs rather than JSON parsing. + +### `aspire sdk export` + +`aspire sdk export --package Name@Version --language typescript` restores the exact package version and writes one canonical JSON document to standard output. Omit `--package` to export `Aspire.Hosting` at the running CLI's SDK version. Diagnostics are written to standard error. + +The top-level fields are `schemaVersion`, `language`, `generator`, `package`, `modules`, and `declarations`. The language exporter owns the schema; the CLI passes it through without reshaping it. diff --git a/src/Aspire.Cli/CliExecutionContext.cs b/src/Aspire.Cli/CliExecutionContext.cs index 0837414b917..79c6eee64b8 100644 --- a/src/Aspire.Cli/CliExecutionContext.cs +++ b/src/Aspire.Cli/CliExecutionContext.cs @@ -7,7 +7,7 @@ namespace Aspire.Cli; -internal sealed class CliExecutionContext(DirectoryInfo workingDirectory, DirectoryInfo hivesDirectory, DirectoryInfo cacheDirectory, DirectoryInfo sdksDirectory, DirectoryInfo logsDirectory, string logFilePath, string identityChannel, bool debugMode = false, DirectoryInfo? homeDirectory = null, DirectoryInfo? packagesDirectory = null, DirectoryInfo? aspireHomeDirectory = null, string? identityVersion = null, string? identityCommit = null, string? nugetServiceIndexOverride = null, bool identityOverridden = false, DirectoryInfo? identityPackagesDirectory = null, bool identityVersionForged = false) +internal sealed class CliExecutionContext(DirectoryInfo workingDirectory, DirectoryInfo hivesDirectory, DirectoryInfo cacheDirectory, DirectoryInfo sdksDirectory, DirectoryInfo logsDirectory, string logFilePath, string identityChannel, bool debugMode = false, DirectoryInfo? homeDirectory = null, DirectoryInfo? packagesDirectory = null, DirectoryInfo? aspireHomeDirectory = null, string? identityVersion = null, string? identityCommit = null, string? nugetServiceIndexOverride = null, bool identityOverridden = false, DirectoryInfo? identityPackagesDirectory = null) { public DirectoryInfo WorkingDirectory { get; } = workingDirectory; public DirectoryInfo HivesDirectory { get; } = hivesDirectory; @@ -103,21 +103,6 @@ internal sealed class CliExecutionContext(DirectoryInfo workingDirectory, Direct /// public bool IdentityOverridden { get; } = identityOverridden; - /// - /// Gets a value indicating whether specifically was supplied by an - /// ASPIRE_CLI_VERSION environment variable. - /// - /// - /// This is deliberately narrower than , which is an aggregate - /// over every identity field and counts the install sidecar as an override. Every install route - /// writes a sidecar carrying channel and version (see - /// docs/specs/cli-identity-sidecar.md), so is - /// for a perfectly ordinary installed CLI and cannot be used to decide - /// whether a version label is trustworthy. The sidecar records what was actually installed; only - /// an environment variable makes the version a per-run claim the CLI cannot stand behind. - /// - public bool IdentityVersionForged { get; } = identityVersionForged; - /// /// Optional replacement for the canonical /// https://api.nuget.org/v3/index.json URL when the CLI emits diff --git a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs b/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs deleted file mode 100644 index 95c393a2a83..00000000000 --- a/src/Aspire.Cli/Commands/Sdk/SdkCommandPreparation.cs +++ /dev/null @@ -1,335 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; -using Aspire.Cli.Configuration; -using Aspire.Cli.Interaction; -using Aspire.Cli.Projects; -using Microsoft.Extensions.Logging; -using Semver; - -namespace Aspire.Cli.Commands.Sdk; - -/// -/// The setup that sdk dump and sdk export both need before they can ask an AppHost -/// server anything: turning command-line integration arguments into references, standing up a -/// throwaway scanner AppHost, and working out which assemblies the caller actually asked about. -/// -/// -/// Only the preparation is shared. The two commands ask different questions of the server and -/// serialize the answers differently, and deliberately keeping that apart is what stops -/// sdk dump from quietly becoming an alias for the canonical export. -/// -internal static class SdkCommandPreparation -{ - /// - /// Parses one integration argument, which is either a path to a .csproj or a package - /// reference in PackageName@Version form (for example Aspire.Hosting.Redis@13.5.0). - /// - /// The raw command-line argument. - /// - /// When , floating and range versions are rejected. Callers that publish - /// artifacts keyed on the version need this; a document published under 13.5.* would - /// describe a different SDK after the next restore. - /// - /// The parsed reference when parsing succeeds. - /// The exit code to return when parsing fails. - /// The user-facing failure reason when parsing fails. - /// when the argument was parsed. - public static bool TryParseIntegrationArgument( - string argument, - bool requireExactVersion, - out IntegrationReference? reference, - out int errorExitCode, - out string? errorMessage) - { - reference = null; - errorExitCode = CliExitCodes.InvalidCommand; - errorMessage = null; - - if (argument.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase)) - { - var projectFile = new FileInfo(argument); - if (!projectFile.Exists) - { - errorExitCode = CliExitCodes.FailedToFindProject; - errorMessage = $"Integration project not found: {projectFile.FullName}"; - return false; - } - - reference = IntegrationReference.FromProject( - IntegrationAssemblyNameResolver.Resolve(projectFile), - projectFile.FullName); - return true; - } - - if (!argument.Contains('@')) - { - errorMessage = $"Invalid integration argument '{argument}'. Expected a .csproj path or PackageName@Version format."; - return false; - } - - var atIndex = argument.LastIndexOf('@'); - var packageName = argument[..atIndex]; - var packageVersion = argument[(atIndex + 1)..]; - - if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion) || packageName.Contains('@')) - { - errorMessage = $"Invalid package format '{argument}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@9.2.0)."; - return false; - } - - if (SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out var parsedVersion)) - { - if (requireExactVersion) - { - // SemVersionStyles.Any accepts abbreviated and decorated forms -- "2.0", "v2.0.0", - // "2.01.0" -- that NuGet normalizes on restore. A caller who asks for Package@2.0 gets - // the 2.0.0 package, so recording the raw text would label the export with a version no - // feed serves. Callers that require an exact version get the normalized string, which is - // the one NuGet resolved. - packageVersion = parsedVersion.ToString(); - } - } - else if (TryNormalizeFourSegmentVersion(packageVersion, out var normalizedFourSegmentVersion)) - { - if (requireExactVersion) - { - packageVersion = normalizedFourSegmentVersion; - } - } - else - { - errorMessage = requireExactVersion - ? $"Invalid version '{packageVersion}' in '{argument}'. Expected an exact NuGet version (e.g. 9.2.0); floating and range versions are not supported." - : $"Invalid version '{packageVersion}' in '{argument}'. Expected a valid NuGet version (e.g. 9.2.0)."; - return false; - } - - reference = IntegrationReference.FromPackage(packageName, packageVersion); - return true; - } - - /// - /// Normalizes a four-segment NuGet version, which semantic versioning cannot represent. - /// - /// - /// NuGet accepts a fourth Revision segment that semver has no room for, so - /// SemVersion.TryParse rejects real - /// package versions such as 5.2.9.0 and 1.2.3.4-beta. Only that shape is handled - /// here, and it follows NuGet's own normalization: a zero revision is dropped - /// (1.2.3.0 becomes 1.2.3) while a non-zero one is kept, leading zeros are - /// stripped, and the pre-release and build-metadata suffixes are carried through untouched. - /// Floating and range syntax still fails, because *, [, and , are not - /// digits. See https://learn.microsoft.com/nuget/concepts/package-versioning. - /// - private static bool TryNormalizeFourSegmentVersion(string version, out string normalized) - { - normalized = string.Empty; - - // The suffix starts at whichever of '-' or '+' comes first, so "1.2.3.4-beta+sha" keeps - // "-beta+sha" and "1.2.3.4+sha" keeps "+sha". - var suffixIndex = version.AsSpan().IndexOfAny('-', '+'); - var numericPart = suffixIndex < 0 ? version : version[..suffixIndex]; - var suffix = suffixIndex < 0 ? string.Empty : version[suffixIndex..]; - - var segments = numericPart.Split('.'); - if (segments.Length != 4) - { - return false; - } - - var parsedSegments = new int[4]; - for (var i = 0; i < segments.Length; i++) - { - // NumberStyles.None rejects signs, whitespace, and thousands separators, so only a bare - // run of digits gets through. - if (!int.TryParse(segments[i], NumberStyles.None, CultureInfo.InvariantCulture, out parsedSegments[i])) - { - return false; - } - } - - // Only the numeric prefix has been checked so far, so "1.2.3.4-" and "1.2.3.4+sha space" - // would still get through. Handing the semver-shaped equivalent back to the parser validates - // the pre-release and build-metadata grammar without reimplementing it. SemVersionStyles.Any - // is deliberate: it allows the leading zeros in labels that NuGet accepts and semver does not - // ("1.2.3-beta.01"), while still rejecting an empty or malformed label. - var semanticEquivalent = $"{parsedSegments[0]}.{parsedSegments[1]}.{parsedSegments[2]}{suffix}"; - if (!SemVersion.TryParse(semanticEquivalent, SemVersionStyles.Any, out _)) - { - return false; - } - - normalized = parsedSegments[3] == 0 - ? semanticEquivalent - : $"{parsedSegments[0]}.{parsedSegments[1]}.{parsedSegments[2]}.{parsedSegments[3]}{suffix}"; - - return true; - } - - /// - /// Finds the first assembly name that more than one integration resolves to. - /// - /// The parsed integration references. - /// The duplicated assembly name, or when there is none. - public static string? FindDuplicateAssemblyName(IReadOnlyList integrations) - => integrations - .GroupBy(integration => integration.Name, StringComparer.OrdinalIgnoreCase) - .FirstOrDefault(group => group.Count() > 1)?.Key; - - /// - /// Gets the exporting assembly names to scope a server query to, or when - /// the caller asked for everything. - /// - /// The parsed integration references. - public static string[]? GetExportingAssemblyNames(IReadOnlyList integrations) - => integrations.Count > 0 - ? [.. integrations.Select(integration => integration.Name).Distinct(StringComparer.OrdinalIgnoreCase)] - : null; - - /// - /// Builds and starts a throwaway AppHost server that has the requested integrations restored, and - /// returns a connected RPC client. - /// - /// - /// The returned owns the temporary directory and the server - /// session; disposing it tears both down. Build failures are reported through - /// and surface as a null session rather than an exception, - /// because a failed restore is a user-facing outcome and not a bug. - /// - /// Creates the scanner AppHost for the temporary directory. - /// Creates the session that runs the scanner AppHost. - /// Reports build failures and rejections to the user. - /// Receives diagnostic detail about the preparation. - /// Prefix for the throwaway project directory. - /// The Aspire SDK version the scanner AppHost is restored at. - /// The integrations to restore into the scanner AppHost. - /// A NuGet source to prefer, or for the configured sources. - /// - /// A pre-flight check run against the created server project before anything is restored, or - /// when the caller has nothing to check. Returning a message rejects the - /// request and reports it through . This exists because the - /// factory only decides between the repository and prebuilt servers once the project is created, - /// and sdk export has to refuse a package the repository server would build from the - /// current checkout instead of restoring at the requested version. - /// - /// Cancellation token. - public static async Task PrepareSessionAsync( - IAppHostServerProjectFactory appHostServerProjectFactory, - IAppHostServerSessionFactory serverSessionFactory, - IInteractionService interactionService, - ILogger logger, - string tempDirectoryPrefix, - string sdkVersion, - IReadOnlyList integrations, - string? packageSourceOverride, - Func? validateProject, - CancellationToken cancellationToken) - { - var tempDirectory = Directory.CreateTempSubdirectory(tempDirectoryPrefix); - var tempDir = tempDirectory.FullName; - var disposeTempDirectory = true; - - try - { - var appHostServerProject = await appHostServerProjectFactory.CreateAsync(tempDir, cancellationToken); - - if (validateProject?.Invoke(appHostServerProject) is string rejection) - { - interactionService.DisplayError(rejection); - return null; - } - - logger.LogDebug("Building AppHost server with {Count} integrations", integrations.Count); - - var prepareResult = await appHostServerProject.PrepareAsync( - sdkVersion, - integrations, - packageSourceOverride: packageSourceOverride, - cancellationToken: cancellationToken); - - if (!prepareResult.Success) - { - interactionService.DisplayError("Failed to build capability scanner."); - if (prepareResult.Output is not null) - { - foreach (var (_, line) in prepareResult.Output.GetLines()) - { - interactionService.DisplayMessage(KnownEmojis.Wrench, line); - } - } - return null; - } - - var serverSession = serverSessionFactory.Create(appHostServerProject, environmentVariables: null, debug: false, gracefulShutdownSignaler: null, shutdownService: null, isolateConsole: false, cancellationToken); - - try - { - // Short-lived RPC session: StartAsync() spawns the server. We never observe the - // exit-code task (WaitForExitAsync) because disposal flows the exit code through the - // activity scope and the only failure mode we care about surfaces via the RPC call. - await serverSession.StartAsync(); - - var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); - - disposeTempDirectory = false; - return new PreparedSdkSession(serverSession, rpcClient, tempDir, logger); - } - catch - { - // Ownership only transfers to PreparedSdkSession once we return one. Until then a - // failed start leaves the scanner process alive and holding the temp directory. - await serverSession.DisposeAsync(); - throw; - } - } - finally - { - if (disposeTempDirectory) - { - DeleteTempDirectory(tempDir, logger); - } - } - } - - internal static void DeleteTempDirectory(string tempDir, ILogger logger) - { - try - { - if (Directory.Exists(tempDir)) - { - Directory.Delete(tempDir, recursive: true); - } - } - catch (Exception ex) - { - logger.LogDebug(ex, "Failed to clean up temp directory {TempDir}", tempDir); - } - } -} - -/// -/// A started AppHost scanner server and its connected RPC client. Disposing tears down the server -/// session and deletes the temporary project directory. -/// -internal sealed class PreparedSdkSession( - IAppHostServerSession session, - IAppHostRpcClient rpcClient, - string tempDirectory, - ILogger logger) : IAsyncDisposable -{ - public IAppHostRpcClient RpcClient { get; } = rpcClient; - - public async ValueTask DisposeAsync() - { - try - { - await session.DisposeAsync(); - } - finally - { - SdkCommandPreparation.DeleteTempDirectory(tempDirectory, logger); - } - } -} diff --git a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs index 0b9497261cc..53695daf237 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs @@ -12,6 +12,7 @@ using Aspire.Cli.Projects; using Aspire.Shared.Json; using Microsoft.Extensions.Logging; +using Semver; using Spectre.Console; using StreamJsonRpc; @@ -97,23 +98,49 @@ protected override async Task ExecuteAsync(ParseResult parseResul foreach (var arg in integrationArgs) { - if (!SdkCommandPreparation.TryParseIntegrationArgument( - arg, - requireExactVersion: false, - out var reference, - out var errorExitCode, - out var errorMessage)) + if (arg.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase)) { - return CommandResult.Failure(errorExitCode, errorMessage!); + var projectFile = new FileInfo(arg); + if (!projectFile.Exists) + { + return CommandResult.Failure(CliExitCodes.FailedToFindProject, $"Integration project not found: {projectFile.FullName}"); + } + + integrations.Add(IntegrationReference.FromProject( + IntegrationAssemblyNameResolver.Resolve(projectFile), + projectFile.FullName)); } + else if (arg.Contains('@')) + { + var atIndex = arg.LastIndexOf('@'); + var packageName = arg[..atIndex]; + var packageVersion = arg[(atIndex + 1)..]; + + if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion) || packageName.Contains('@')) + { + return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Invalid package format '{arg}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@9.2.0)."); + } + + if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out _)) + { + return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Invalid version '{packageVersion}' in '{arg}'. Expected a valid NuGet version (e.g. 9.2.0)."); + } - _logger.LogDebug("Parsed integration reference {IntegrationName}", reference!.Name); - integrations.Add(reference); + _logger.LogDebug("Parsed package reference {PackageName} version {Version}", packageName, packageVersion); + integrations.Add(IntegrationReference.FromPackage(packageName, packageVersion)); + } + else + { + return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Invalid integration argument '{arg}'. Expected a .csproj path or PackageName@Version format."); + } } - if (SdkCommandPreparation.FindDuplicateAssemblyName(integrations) is { } duplicateAssemblyName) + var duplicateIntegration = integrations + .GroupBy(integration => integration.Name, StringComparer.OrdinalIgnoreCase) + .FirstOrDefault(group => group.Count() > 1); + if (duplicateIntegration is not null) { - return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Multiple integrations resolve to assembly name '{duplicateAssemblyName}'."); + return CommandResult.Failure(CliExitCodes.InvalidCommand, $"Multiple integrations resolve to assembly name '{duplicateIntegration.Key}'."); } if (outputDirectory is not null) @@ -139,60 +166,97 @@ private async Task DumpCapabilitiesAsync( OutputFormat format, CancellationToken cancellationToken) { - await using var session = await SdkCommandPreparation.PrepareSessionAsync( - _appHostServerProjectFactory, - _serverSessionFactory, - InteractionService, - _logger, - "aspire-sdk-dump-", - ExecutionContext.IdentityVersion, - integrations, - packageSourceOverride: null, - validateProject: null, - cancellationToken); - - if (session is null) + var tempDirectory = Directory.CreateTempSubdirectory("aspire-sdk-dump-"); + var tempDir = tempDirectory.FullName; + + try { - return CliExitCodes.FailedToBuildArtifacts; - } + var appHostServerProject = await _appHostServerProjectFactory.CreateAsync(tempDir, cancellationToken); + + _logger.LogDebug("Building AppHost server for capability scanning with {Count} integrations", integrations.Count); + + var prepareResult = await appHostServerProject.PrepareAsync( + ExecutionContext.IdentityVersion, + integrations, + cancellationToken: cancellationToken); + + if (!prepareResult.Success) + { + InteractionService.DisplayError("Failed to build capability scanner."); + if (prepareResult.Output is not null) + { + foreach (var (_, line) in prepareResult.Output.GetLines()) + { + InteractionService.DisplayMessage(KnownEmojis.Wrench, line); + } + } + return CliExitCodes.FailedToBuildArtifacts; + } - var exportAssemblyNames = SdkCommandPreparation.GetExportingAssemblyNames(integrations); + await using var serverSession = _serverSessionFactory.Create(appHostServerProject, environmentVariables: null, debug: false, gracefulShutdownSignaler: null, shutdownService: null, isolateConsole: false, cancellationToken); + // Short-lived RPC session: StartAsync() spawns the server. We never observe the + // exit-code task (WaitForExitAsync) because disposal flows the exit code through the + // activity scope and the only failure mode we care about surfaces via the RPC call below. + await serverSession.StartAsync(); - _logger.LogDebug("Fetching capabilities via RPC"); - var capabilities = exportAssemblyNames is not null - ? await session.RpcClient.GetCapabilitiesForAssembliesAsync(exportAssemblyNames, cancellationToken) - : await session.RpcClient.GetCapabilitiesAsync(cancellationToken); + // Connect and get capabilities + var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); - PrepareCapabilitiesForOutput(capabilities, integrations); + var exportAssemblyNames = integrations.Count > 0 + ? integrations.Select(i => i.Name).Distinct(StringComparer.OrdinalIgnoreCase).ToArray() + : null; - // Format the output - var output = format switch - { - OutputFormat.Json => FormatJson(capabilities), - OutputFormat.Ci => FormatCi(capabilities), - _ => FormatPretty(capabilities) - }; + _logger.LogDebug("Fetching capabilities via RPC"); + var capabilities = exportAssemblyNames is not null + ? await rpcClient.GetCapabilitiesForAssembliesAsync(exportAssemblyNames, cancellationToken) + : await rpcClient.GetCapabilitiesAsync(cancellationToken); - // Write output - if (outputFile is not null) - { - var outputDir = outputFile.Directory; - if (outputDir is not null && !outputDir.Exists) + PrepareCapabilitiesForOutput(capabilities, integrations); + + // Format the output + var output = format switch + { + OutputFormat.Json => FormatJson(capabilities), + OutputFormat.Ci => FormatCi(capabilities), + _ => FormatPretty(capabilities) + }; + + // Write output + if (outputFile is not null) + { + var outputDir = outputFile.Directory; + if (outputDir is not null && !outputDir.Exists) + { + outputDir.Create(); + } + await File.WriteAllTextAsync(outputFile.FullName, output, cancellationToken); + InteractionService.DisplaySuccess($"Capabilities written to {outputFile.FullName}"); + } + else { - outputDir.Create(); + // Output to stdout + InteractionService.DisplayRawText(output, consoleOverride: ConsoleOutput.Standard); } - await File.WriteAllTextAsync(outputFile.FullName, output, cancellationToken); - InteractionService.DisplaySuccess($"Capabilities written to {outputFile.FullName}"); + + // Return error code if there are errors in diagnostics + var hasErrors = capabilities.Diagnostics.Exists(d => d.Severity == "Error"); + return hasErrors ? CliExitCodes.InvalidCommand : CliExitCodes.Success; } - else + finally { - // Output to stdout - InteractionService.DisplayRawText(output, consoleOverride: ConsoleOutput.Standard); + // Clean up temp directory + try + { + if (Directory.Exists(tempDir)) + { + Directory.Delete(tempDir, recursive: true); + } + } + catch (Exception ex) + { + _logger.LogDebug(ex, "Failed to clean up temp directory {TempDir}", tempDir); + } } - - // Return error code if there are errors in diagnostics - var hasErrors = capabilities.Diagnostics.Exists(d => d.Severity == "Error"); - return hasErrors ? CliExitCodes.InvalidCommand : CliExitCodes.Success; } private async Task DumpCapabilitiesToDirectoryAsync( @@ -201,45 +265,77 @@ private async Task DumpCapabilitiesToDirectoryAsync( OutputFormat format, CancellationToken cancellationToken) { - await using var session = await SdkCommandPreparation.PrepareSessionAsync( - _appHostServerProjectFactory, - _serverSessionFactory, - InteractionService, - _logger, - "aspire-sdk-dump-", - ExecutionContext.IdentityVersion, - integrations, - packageSourceOverride: null, - validateProject: null, - cancellationToken); - - if (session is null) + var tempDirectory = Directory.CreateTempSubdirectory("aspire-sdk-dump-"); + var tempDir = tempDirectory.FullName; + + try { - return CliExitCodes.FailedToBuildArtifacts; - } + var appHostServerProject = await _appHostServerProjectFactory.CreateAsync(tempDir, cancellationToken); - outputDirectory.Create(); + _logger.LogDebug("Building AppHost server for batched capability scanning with {Count} integrations", integrations.Count); - var dumpTasks = integrations - .Select(integration => DumpIntegrationCapabilitiesAsync(session.RpcClient, integration, outputDirectory, format, cancellationToken)) - .ToArray(); + var prepareResult = await appHostServerProject.PrepareAsync( + ExecutionContext.IdentityVersion, + integrations, + cancellationToken: cancellationToken); - var dumpResults = await Task.WhenAll(dumpTasks); - var failures = dumpResults.Where(result => !result.Success).ToArray(); - if (failures.Length > 0) - { - InteractionService.DisplayError("Failed to dump capabilities for one or more integrations."); - foreach (var failure in failures) + if (!prepareResult.Success) { - InteractionService.DisplayMessage(KnownEmojis.CrossMark, $"{failure.IntegrationName}: {failure.ErrorMessage}"); + InteractionService.DisplayError("Failed to build capability scanner."); + if (prepareResult.Output is not null) + { + foreach (var (_, line) in prepareResult.Output.GetLines()) + { + InteractionService.DisplayMessage(KnownEmojis.Wrench, line); + } + } + return CliExitCodes.FailedToBuildArtifacts; } - return CliExitCodes.FailedToBuildArtifacts; - } + await using var serverSession = _serverSessionFactory.Create(appHostServerProject, environmentVariables: null, debug: false, gracefulShutdownSignaler: null, shutdownService: null, isolateConsole: false, cancellationToken); + // Short-lived RPC session: StartAsync() spawns the server. We never observe the + // exit-code task (WaitForExitAsync) because disposal flows the exit code through the + // activity scope and the only failure mode we care about surfaces via the RPC call below. + await serverSession.StartAsync(); + + var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); + outputDirectory.Create(); + + var dumpTasks = integrations + .Select(integration => DumpIntegrationCapabilitiesAsync(rpcClient, integration, outputDirectory, format, cancellationToken)) + .ToArray(); + + var dumpResults = await Task.WhenAll(dumpTasks); + var failures = dumpResults.Where(result => !result.Success).ToArray(); + if (failures.Length > 0) + { + InteractionService.DisplayError("Failed to dump capabilities for one or more integrations."); + foreach (var failure in failures) + { + InteractionService.DisplayMessage(KnownEmojis.CrossMark, $"{failure.IntegrationName}: {failure.ErrorMessage}"); + } + + return CliExitCodes.FailedToBuildArtifacts; + } - return dumpResults.Any(result => result.HasErrors) - ? CliExitCodes.InvalidCommand - : CliExitCodes.Success; + return dumpResults.Any(result => result.HasErrors) + ? CliExitCodes.InvalidCommand + : CliExitCodes.Success; + } + finally + { + try + { + if (Directory.Exists(tempDir)) + { + Directory.Delete(tempDir, recursive: true); + } + } + catch (Exception ex) + { + _logger.LogDebug(ex, "Failed to clean up temp directory {TempDir}", tempDir); + } + } } private async Task DumpIntegrationCapabilitiesAsync( @@ -285,18 +381,10 @@ private void PrepareCapabilitiesForOutput(CapabilitiesInfo capabilities, IEnumer capabilities.Diagnostics.RemoveAll(d => d.Severity == "Info"); - // This records what the caller asked to scan, not what NuGet resolved. `sdk dump` restores - // with a minimum-version reference (see IntegrationReference.GetRestoreVersionRange) and, in - // a repository checkout, may build a first-party integration from src/ instead, so a scan of - // 13.4.0 can legitimately report on 13.4.1. That is intentional: dump is an inspection tool, - // and `--format ci` — the format the checked-in *.ats.txt baselines use — carries no package - // versions at all, so nothing version-keyed is published from this block. `sdk export` is the - // command that has to make the label true, and it pins the restore and rejects checkout skew. var packageVersions = integrations .Where(i => i.IsPackageReference) .Select(i => new PackageInfo { Name = i.Name, Version = i.Version! }) .ToList(); - if (packageVersions.Count > 0) { capabilities.Packages = packageVersions; @@ -421,31 +509,15 @@ private static string FormatCi(CapabilitiesInfo capabilities) var paramStr = string.Join(", ", c.Parameters.Select(p => { var optional = p.IsOptional ? "?" : ""; - var nullable = p.IsNullable ? "?" : ""; - return string.Format(CultureInfo.InvariantCulture, "{0}{1}: {2}{3}", p.Name, optional, p.Type?.TypeId ?? "unknown", nullable); + return string.Format(CultureInfo.InvariantCulture, "{0}{1}: {2}", p.Name, optional, p.Type?.TypeId ?? "unknown"); })); var returnStr = c.ReturnType?.TypeId ?? "void"; - - // [AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] makes the - // projected TypeScript name differ from the capability id, and the generated options - // interface is named after the projected name. The annotation is emitted only for that - // aliased minority so the surface stays unchanged for everything else: - // Pkg/withRedisCommanderHostPort(port?: number) -> Pkg/Handle [method=withHostPort] - var methodSuffix = string.IsNullOrEmpty(c.MethodName) || string.Equals(c.MethodName, GetCapabilityMethodSegment(c.CapabilityId), StringComparison.Ordinal) - ? "" - : string.Format(CultureInfo.InvariantCulture, " [method={0}]", c.MethodName); - sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0}({1}) -> {2}{3}", c.CapabilityId, paramStr, returnStr, methodSuffix)); + sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0}({1}) -> {2}", c.CapabilityId, paramStr, returnStr)); } return sb.ToString(); } - private static string GetCapabilityMethodSegment(string capabilityId) - { - var slashIndex = capabilityId.IndexOf('/'); - return slashIndex < 0 ? capabilityId : capabilityId[(slashIndex + 1)..]; - } - private static string FormatPretty(CapabilitiesInfo capabilities) { var sb = new StringBuilder(); @@ -658,10 +730,6 @@ internal sealed class CapabilitiesInfo internal sealed class PackageInfo { public string Name { get; set; } = ""; - - // The version that was requested on the command line, not the one NuGet resolved. Restore uses a - // minimum-version reference, so the scanned assembly can be newer; see the comment in - // SdkDumpCommand.PrepareCapabilitiesForOutput for why dump keeps requested-version semantics. public string Version { get; set; } = ""; } diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 4b10a3345ae..9a898c29e32 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -9,20 +9,16 @@ using Microsoft.Extensions.Logging; using Semver; using StreamJsonRpc; +using StreamJsonRpc.Protocol; namespace Aspire.Cli.Commands.Sdk; /// -/// Command for exporting the canonical API reference of an Aspire package for a target language. -/// -/// Usage: -/// aspire sdk export --language typescript # Core Aspire.Hosting at this CLI's SDK version -/// aspire sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0 +/// Exports a package's canonical API reference for a target language. /// /// -/// The output is consumed by documentation pipelines, so stdout carries exactly one JSON document -/// and nothing else. Every status message, warning, and error goes to stderr, which is what makes -/// aspire sdk export ... > api.json produce a usable file. +/// Standard output contains only the JSON document. Preparation diagnostics and errors are written +/// to standard error so the command can be redirected directly to a file. /// internal sealed class SdkExportCommand : BaseCommand { @@ -38,17 +34,10 @@ internal sealed class SdkExportCommand : BaseCommand Description = "Target language for the API export (e.g., typescript).", Required = true }; + private static readonly Option s_packageOption = new("--package", "-p") { - Description = "Package to export in PackageName@Version format. Defaults to the core Aspire.Hosting package at this CLI's SDK version." - }; - private static readonly Option s_sourceOption = new("--source", "-s") - { - Description = "NuGet package source to restore the package from." - }; - private static readonly Option s_outputOption = new("--output", "-o") - { - Description = "Output file. If not specified, the document is written to stdout." + Description = "Package to export in PackageName@Version form. Defaults to Aspire.Hosting at this CLI's SDK version." }; public SdkExportCommand( @@ -57,459 +46,239 @@ public SdkExportCommand( ILanguageDiscovery languageDiscovery, ILogger logger, CommonCommandServices services) - : base("export", "Export the canonical API reference for an Aspire package in a target language.", services) + : base("export", "Export a canonical package API reference.", services) { _appHostServerProjectFactory = appHostServerProjectFactory; _serverSessionFactory = serverSessionFactory; _languageDiscovery = languageDiscovery; _logger = logger; - // Not marked Hidden: the parent `sdk` command already hides the whole subtree, and setting - // Hidden here additionally suppresses this command's own --help output. Options.Add(s_languageOption); Options.Add(s_packageOption); - Options.Add(s_sourceOption); - Options.Add(s_outputOption); } protected override async Task ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken) { - // This command always emits machine-readable JSON, so it has no --format option for - // BaseCommand's json redirect to key off. Without this, preparation diagnostics and the - // --output success message land on stdout and corrupt the document a caller is piping. - // The JSON write overrides back to stdout explicitly, and an explicit override wins. InteractionService.Console = ConsoleOutput.Error; var language = parseResult.GetValue(s_languageOption)!; - var package = parseResult.GetValue(s_packageOption); - var packageSource = parseResult.GetValue(s_sourceOption); - var outputFile = parseResult.GetValue(s_outputOption); + if (string.IsNullOrWhiteSpace(language)) + { + return CommandResult.Failure(CliExitCodes.InvalidCommand, "The export language cannot be empty."); + } - string packageName; - string packageVersion; + var packageArgument = parseResult.GetValue(s_packageOption); + var packageName = CorePackageName; + var packageVersion = ExecutionContext.IdentitySdkVersion; var integrations = new List(); - if (string.IsNullOrWhiteSpace(package)) - { - // Documentation has to describe the SDK this CLI generates against, so the default is - // the CLI's own identity version rather than whatever the feed currently calls latest. - // IdentitySdkVersion, not IdentityVersion: an informational version carries the build - // metadata suffix (13.4.0-preview.1.25366.3+abc123), and NuGet does not treat that as - // part of package identity, so recording it verbatim would label the export with a - // version no feed serves -- the same drift the explicit package path normalizes away. - packageName = CorePackageName; - packageVersion = ExecutionContext.IdentitySdkVersion; - } - else + if (!string.IsNullOrWhiteSpace(packageArgument)) { - if (!SdkCommandPreparation.TryParseIntegrationArgument( - package, - requireExactVersion: true, - out var reference, - out var errorExitCode, - out var errorMessage)) - { - return CommandResult.Failure(errorExitCode, errorMessage!); - } - - if (reference!.Version is null) + if (!TryParsePackage(packageArgument, out packageName, out packageVersion, out var errorMessage)) { - return CommandResult.Failure( - CliExitCodes.InvalidCommand, - $"Invalid package '{package}'. Expected PackageName@Version (e.g. Aspire.Hosting.Redis@13.5.0); project references are not supported by sdk export."); + return CommandResult.Failure(CliExitCodes.InvalidCommand, errorMessage); } - // SemVer build metadata is not part of NuGet package identity - // (https://semver.org/#spec-item-10), so `Contoso@2.0.0+fake` restores exactly the - // package `Contoso@2.0.0` does. Recording the requested string verbatim would publish - // that package's surface under a version no feed can serve, which is precisely the - // exact-version guarantee this command exists to make. Normalizing once here keeps the - // first-party guard, the restore pin, and the exported label naming the same version. - packageVersion = StripBuildMetadata(reference.Version); - - // NuGet package ids are case-insensitive, so `aspire.hosting` names the core package - // exactly as `Aspire.Hosting` does: - // https://learn.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#package-identifiers. - // Nothing downstream is. The substitution probe resolves the name through the - // filesystem, the generated scanner project-references src/Aspire.Hosting under the - // canonical spelling no matter what was asked for, and the exported document records - // this string verbatim as the package identity documentation is keyed on. Settling on - // the canonical spelling here — before the scanner project is created and validated — - // is what keeps the guard, the scanner, and the label describing one package. - var isCorePackage = string.Equals(reference.Name, CorePackageName, StringComparison.OrdinalIgnoreCase); - packageName = isCorePackage ? CorePackageName : reference.Name; - - if (IsFirstPartyHostingPackage(packageName)) + if (string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase)) { + packageName = CorePackageName; if (!string.Equals(packageVersion, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) { return CommandResult.Failure( CliExitCodes.InvalidCommand, - $"This CLI can only export first-party Aspire packages at {ExecutionContext.IdentitySdkVersion}, but {packageName}@{packageVersion} was requested. " + - $"The TypeScript generator is restored at this CLI's version, so exporting a different package version would describe a mixed SDK surface. " + - $"Run the export with the {packageVersion} CLI instead."); + $"This CLI exports {CorePackageName} at {ExecutionContext.IdentitySdkVersion}; {packageVersion} was requested."); } } - - if (!isCorePackage) + else { - // Pin the requested version: a bare NuGet version is a minimum, so an unavailable - // version would restore as a later one and be published under the wrong number. - // Use packageName/packageVersion rather than the raw reference so the restored - // reference and the exported label can never name a different package or version. - integrations.Add(IntegrationReference.FromExactPackage(packageName, packageVersion)); + integrations.Add(CreateExactPackageReference(packageName, packageVersion)); } } - // The code generator lives in a separate package that the scanner AppHost does not reference - // by default, so without this the server loads no generators and every export fails with - // "No code generator found". `sdk generate` adds the same package for the same reason. - var languageInfo = await GetLanguageInfoAsync(language, cancellationToken); - var codeGenPackage = languageInfo is null - ? null - : await GetCodeGenerationPackageAsync(languageInfo, cancellationToken); - if (codeGenPackage is not null) + var languageInfo = await FindLanguageAsync(language, cancellationToken); + if (languageInfo is not null) { - integrations.Add(IntegrationReference.FromExactPackage(codeGenPackage, ExecutionContext.IdentityVersion)); + var codeGenerationPackage = await _languageDiscovery.GetPackageForLanguageAsync( + languageInfo.LanguageId, + cancellationToken); + + if (codeGenerationPackage is not null) + { + // Match sdk generate: repository mode uses the generator from this checkout, while + // installed CLIs restore the package that accompanies their build. + integrations.Add(IntegrationReference.FromPackage( + codeGenerationPackage, + ExecutionContext.IdentityVersion)); + } } - // The server keys generators by ICodeGenerator.Language ("TypeScript"), not by the language - // id or the abbreviation the user typed, so the matched generator name is what crosses the - // RPC. `aspire sdk export --language typescript/nodejs` resolves its package here and would - // otherwise fail with "No code generator found" on the far side. `sdk generate` sends the - // same value. An unresolved language is forwarded verbatim so the server produces the - // authoritative unsupported-language error rather than this command guessing at one. - return CommandResult.FromExitCode(await ExportApiAsync( + var exitCode = await ExportApiAsync( languageInfo?.CodeGenerator ?? language, packageName, packageVersion, integrations, - codeGenPackage, - packageSource, - outputFile, - cancellationToken)); + cancellationToken); + + return CommandResult.FromExitCode(exitCode); } - /// - /// Resolves the language the user asked for, matching the way sdk generate resolves it. - /// Returns when the language is unknown so that the server produces the - /// authoritative unsupported-language error. - /// - private async Task GetLanguageInfoAsync(string language, CancellationToken cancellationToken) + private async Task FindLanguageAsync(string language, CancellationToken cancellationToken) { - // --language is required, but System.CommandLine considers `--language ""` supplied, and - // every language id starts with the empty string. Without this guard the prefix match would - // hand back whichever language happened to be discovered first and export it as though the - // user had asked for it. - if (string.IsNullOrWhiteSpace(language)) - { - return null; - } - try { var languages = await _languageDiscovery.GetAvailableLanguagesAsync(cancellationToken); - - return languages.FirstOrDefault(l => - l.LanguageId.Value.StartsWith(language, StringComparison.OrdinalIgnoreCase) || - l.CodeGenerator.Equals(language, StringComparison.OrdinalIgnoreCase)); + return languages.FirstOrDefault(candidate => + candidate.LanguageId.Value.StartsWith(language, StringComparison.OrdinalIgnoreCase) || + candidate.CodeGenerator.Equals(language, StringComparison.OrdinalIgnoreCase)); } catch (Exception ex) when (ex is not OperationCanceledException) { - _logger.LogDebug(ex, "Failed to resolve the language {Language}", language); + _logger.LogDebug(ex, "Failed to resolve export language {Language}", language); return null; } } - /// - /// Resolves the code generation package that provides the requested language. Returns - /// when discovery fails so that the export still runs and the server - /// reports the missing generator. - /// - private async Task GetCodeGenerationPackageAsync(LanguageInfo languageInfo, CancellationToken cancellationToken) + private async Task ExportApiAsync( + string language, + string packageName, + string packageVersion, + IReadOnlyList integrations, + CancellationToken cancellationToken) { + var tempDirectory = Directory.CreateTempSubdirectory("aspire-sdk-export-"); + var tempDirectoryPath = tempDirectory.FullName; + try { - return await _languageDiscovery.GetPackageForLanguageAsync(languageInfo.LanguageId, cancellationToken); - } - catch (Exception ex) when (ex is not OperationCanceledException) - { - _logger.LogDebug(ex, "Failed to resolve the code generation package for language {Language}", languageInfo.LanguageId.Value); - return null; - } - } + var appHostServerProject = await _appHostServerProjectFactory.CreateAsync( + tempDirectoryPath, + cancellationToken); - /// - /// Drops SemVer build metadata so 13.5.0+abc123 and 13.5.0 compare equal, matching - /// how normalizes this CLI's own version. - /// - private static string StripBuildMetadata(string version) - { - var plusIndex = version.IndexOf('+', StringComparison.Ordinal); - return plusIndex < 0 ? version : version[..plusIndex]; - } + var prepareResult = await appHostServerProject.PrepareAsync( + ExecutionContext.IdentityVersion, + integrations, + cancellationToken: cancellationToken); - private static bool IsFirstPartyHostingPackage(string packageName) - => string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase) || - packageName.StartsWith($"{CorePackageName}.", StringComparison.OrdinalIgnoreCase); - - /// - /// Refuses an export the scanner would satisfy from a local checkout instead of restoring the - /// requested package version. - /// - /// - /// - /// In repository development mode the scanner AppHost replaces every first-party - /// Aspire.Hosting.* package reference that exists under src/ with that project and - /// discards the requested version, so the checkout's API surface would be published under - /// someone else's version number. That is the same stale-signature problem the core-package - /// guard prevents, so this refuses for the same reason. Asking for the version this CLI was - /// built from is still allowed: that is exactly what the checkout contains. Third-party packages - /// are never substituted, so they fall straight through. - /// - /// - /// The check cannot rest on alone, because - /// that value is overrideable by design (ASPIRE_CLI_VERSION, the install sidecar) and - /// would let a caller name local source whatever they like. The checkout's own version line is - /// the independent half; the identity is still compared so a checkout on the right line cannot - /// publish a neighbouring build's number. - /// - /// - /// The core package needs both halves as well. Neither - /// implementation honours the requested SDK version — the repository scanner builds - /// src/Aspire.Hosting and the prebuilt scanner loads the assemblies bundled with the CLI - /// — so a core export always describes this CLI, and the label has to be this CLI's real - /// version. The comparison that enforces that runs before any project is created, but it - /// compares the request against the identity while the default request is the identity, - /// so on its own it only catches an explicitly wrong --package. Two cases get past it. - /// An ASPIRE_CLI_VERSION override makes the identity itself caller-controlled, and the - /// prebuilt scanner has no second signal to check it against, so that override is refused - /// outright. It has to be that specific signal rather than the IdentityOverridden - /// aggregate, which every installed CLI trips through its install sidecar. Repository mode - /// is entered through ASPIRE_REPO_ROOT, which is not an identity field at all, so an - /// installed CLI can be pointed at a checkout on a different version line with no override in - /// effect; the core package therefore falls through to the same checkout comparison every other - /// first-party package gets, which is available because src/Aspire.Hosting is always - /// project-referenced by the generated scanner. - /// - /// - /// The scanner AppHost that will restore the export. - /// The package being exported. - /// The version the caller asked for. - /// The code generation package the export will load, when one was resolved. - /// The rejection reason, or when the request is exportable. - private string? ValidateRequestedPackageIsRestorable(IAppHostServerProject serverProject, string packageName, string packageVersion, string? codeGenPackage) - { - var isCorePackage = string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase); + if (!prepareResult.Success) + { + InteractionService.DisplayError("Failed to build the API export scanner."); + if (prepareResult.Output is not null) + { + foreach (var (_, line) in prepareResult.Output.GetLines()) + { + InteractionService.DisplayMessage(KnownEmojis.Wrench, line); + } + } - if (isCorePackage && ExecutionContext.IdentityVersionForged) - { - // The prebuilt scanner has no second signal: the core assemblies come from the bundle - // this CLI shipped with, so a forged version leaves nothing to check the label against. - // Repository mode does have one, and falls through to it below. - // - // This tests IdentityVersionForged rather than the IdentityOverridden aggregate on - // purpose. Every install route writes a sidecar carrying channel and version, so the - // aggregate is true for an ordinary installed CLI and gating on it rejected the - // advertised default export on exactly the installs the error told callers to use. - return $"The scanner loads the {CorePackageName} assemblies this CLI ships with, so an export of it describes this CLI. " + - $"This run claims a different version through ASPIRE_CLI_VERSION, so the export cannot be attributed to a real build of {packageVersion}. " + - $"Re-run without the override, or export {CorePackageName} from an installed CLI."; - } + return CliExitCodes.FailedToBuildArtifacts; + } - // The name arrives canonical: the caller settles the core package on CorePackageName before - // the scanner project is created, because this lookup resolves through the filesystem and - // would miss `aspire.hosting` on a case-sensitive one while the scanner still built - // src/Aspire.Hosting. - if (serverProject.GetLocalProjectSubstitution(packageName) is not { } substitution) - { - return ValidateCodeGenerationPackageIsRestorable(serverProject, codeGenPackage); - } + await using var serverSession = _serverSessionFactory.Create( + appHostServerProject, + environmentVariables: null, + debug: false, + gracefulShutdownSignaler: null, + shutdownService: null, + isolateConsole: false, + cancellationToken); - var preamble = $"This CLI runs from an Aspire repository checkout, so {packageName} is built from {substitution.ProjectPath} " + - $"instead of being restored from a package feed."; + await serverSession.StartAsync(); + var rpcClient = await serverSession.GetRpcClientAsync(cancellationToken); - if (ExecutionContext.IdentityVersionForged) - { - // A forged version makes this run an emulation of a build the checkout is not, which is - // exactly the combination that cannot be checked: both the source and the label are - // caller-controlled. Every other ASPIRE_CLI_* override stays available here, and a - // sidecar version does not qualify because the installer wrote it. - return $"{preamble} This run also claims a version through ASPIRE_CLI_VERSION, so nothing can confirm the " + - $"checkout really is {packageVersion}. Re-run without the override, or export {packageName} from an installed CLI."; - } + JsonElement export; + try + { + export = await rpcClient.ExportApiAsync( + language, + packageName, + packageVersion, + cancellationToken); + } + catch (NotSupportedException ex) + { + InteractionService.DisplayError(ex.Message); + return CliExitCodes.InvalidCommand; + } + catch (RemoteInvocationException ex) when (ex.ErrorCode == (int)JsonRpcErrorCode.InvalidParams) + { + InteractionService.DisplayError(ex.Message); + return CliExitCodes.InvalidCommand; + } + catch (Exception ex) when (ex is RemoteInvocationException or AppHostCodeGenerationException) + { + InteractionService.DisplayError(ex.Message); + return CliExitCodes.FailedToBuildArtifacts; + } - if (substitution.CheckoutVersionPrefix is not string checkoutPrefix) - { - return $"{preamble} This checkout does not say which version it builds (eng/Versions.props is missing or unreadable), " + - $"so an export labelled {packageVersion} cannot be verified. Export {packageName} from an installed CLI instead."; - } + var json = export.GetRawText() + .Replace("\r\n", "\n", StringComparison.Ordinal) + .Replace('\r', '\n'); - if (!SemVersion.TryParse(packageVersion, SemVersionStyles.Any, out var requestedVersion) - || $"{requestedVersion.Major}.{requestedVersion.Minor}.{requestedVersion.Patch}" != checkoutPrefix) - { - // A core export takes its version from this CLI's identity rather than from --package, - // so telling the caller to re-run with the requested version's CLI would name the CLI - // they are already running. There the checkout is the half that has to move. - return isCorePackage - ? $"{preamble} That checkout builds {checkoutPrefix}, but this CLI is {packageVersion}, and exporting it " + - $"would describe the checkout's API surface under this CLI's version. " + - $"Export {packageName} from a {checkoutPrefix} CLI, or point this one at a {StripBuildMetadata(packageVersion)} checkout." - : $"{preamble} That checkout builds {checkoutPrefix}, but {packageVersion} was requested, and exporting it " + - $"would describe the checkout's API surface under the requested version. " + - $"Run the export with the {StripBuildMetadata(packageVersion)} CLI instead."; + InteractionService.DisplayRawText(json, consoleOverride: ConsoleOutput.Standard); + return CliExitCodes.Success; } - - var requested = StripBuildMetadata(packageVersion); - if (!string.Equals(requested, ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) + finally { - return $"{preamble} That checkout is {ExecutionContext.IdentitySdkVersion}, but {packageVersion} was requested, " + - $"and exporting it would describe the checkout's API surface under the requested version. " + - $"Run the export with the {requested} CLI, or request {packageName}@{ExecutionContext.IdentitySdkVersion}."; + try + { + if (Directory.Exists(tempDirectoryPath)) + { + Directory.Delete(tempDirectoryPath, recursive: true); + } + } + catch (Exception ex) + { + _logger.LogDebug(ex, "Failed to clean up API export directory {TempDirectory}", tempDirectoryPath); + } } - - return ValidateCodeGenerationPackageIsRestorable(serverProject, codeGenPackage); } - /// - /// Rejects an export whose code generator would be built from a checkout that does not match this - /// CLI, or when the generator is exportable. - /// - /// - /// The generator reference is pinned to when it is - /// added, but repository mode substitutes every Aspire.Hosting* reference with the - /// matching project under src/ and that substitution ignores the pin. The exported document - /// is labelled with the requested package version and records the generator's output shape, so a - /// checkout on a different version line silently publishes generator output this CLI never - /// produced. The request-level checks above cannot catch it: for a third-party integration they - /// return before looking at anything, because nothing under src/ carries that name. - /// - private string? ValidateCodeGenerationPackageIsRestorable(IAppHostServerProject serverProject, string? codeGenPackage) - { - if (codeGenPackage is null || serverProject.GetLocalProjectSubstitution(codeGenPackage) is not { } substitution) - { - return null; - } - - var preamble = $"This CLI runs from an Aspire repository checkout, so the {codeGenPackage} code generator is built from " + - $"{substitution.ProjectPath} instead of being restored at this CLI's version."; - - if (ExecutionContext.IdentityVersionForged) - { - return $"{preamble} This run also claims a version through ASPIRE_CLI_VERSION, so nothing can confirm the " + - $"checkout really is {ExecutionContext.IdentityVersion}. Re-run without the override, or export from an installed CLI."; - } + private static IntegrationReference CreateExactPackageReference(string packageName, string packageVersion) + => IntegrationReference.FromPackage(packageName, $"[{packageVersion}]"); - if (substitution.CheckoutVersionPrefix is not string checkoutPrefix) - { - return $"{preamble} This checkout does not say which version it builds (eng/Versions.props is missing or unreadable), " + - $"so the generated document cannot be attributed to a known generator. Export from an installed CLI instead."; - } - - // Compare on Major.Minor.Patch only. CheckoutVersionPrefix is that shape by construction while - // the identity carries whatever prerelease label this build was stamped with, so comparing the - // strings rejected the ordinary local development case where the checkout is exactly this CLI. - if (!SemVersion.TryParse(ExecutionContext.IdentitySdkVersion, SemVersionStyles.Any, out var identityVersion) - || $"{identityVersion.Major}.{identityVersion.Minor}.{identityVersion.Patch}" != checkoutPrefix) - { - return $"{preamble} That checkout builds {checkoutPrefix}, but this CLI is {ExecutionContext.IdentitySdkVersion}, so the " + - $"export would describe the checkout's generator output as this CLI's. " + - $"Export from a {checkoutPrefix} CLI, or point this one at a {ExecutionContext.IdentitySdkVersion} checkout."; - } - - return null; - } - - private async Task ExportApiAsync( - string language, - string packageName, - string packageVersion, - List integrations, - string? codeGenPackage, - string? packageSource, - FileInfo? outputFile, - CancellationToken cancellationToken) + private static bool TryParsePackage( + string argument, + out string packageName, + out string packageVersion, + out string errorMessage) { - // Both scanner projects ignore this value -- DotNetBasedAppHostServerProject.PrepareAsync - // never reads it, and PrebuiltAppHostServer restores from the integration references alone -- - // so it is a label, not a pin. What actually makes the export describe the requested SDK is - // the exact IntegrationReference above plus ValidateRequestedPackageIsRestorable below. It is - // still derived from the documented version so any consumer that starts honoring it agrees - // with what was exported rather than with the CLI's bundled SDK. - var sdkVersion = string.Equals(packageName, CorePackageName, StringComparison.OrdinalIgnoreCase) - ? packageVersion - : ExecutionContext.IdentityVersion; - - string? rejection = null; - - await using var session = await SdkCommandPreparation.PrepareSessionAsync( - _appHostServerProjectFactory, - _serverSessionFactory, - InteractionService, - _logger, - "aspire-sdk-export-", - sdkVersion, - integrations, - packageSource, - validateProject: serverProject => rejection = ValidateRequestedPackageIsRestorable(serverProject, packageName, packageVersion, codeGenPackage), - cancellationToken); - - if (session is null) + packageName = string.Empty; + packageVersion = string.Empty; + errorMessage = string.Empty; + + // Parse the literal PackageName@Version shape. NuGet package IDs cannot contain '@', so an + // additional separator is malformed rather than part of the package name. + var separatorIndex = argument.LastIndexOf('@'); + if (separatorIndex <= 0 || + separatorIndex == argument.Length - 1 || + argument.AsSpan(0, separatorIndex).Contains('@')) { - // A rejection is a usage error the caller fixes by asking for a different version or - // running a different CLI, so it must not look like the scanner failed to build. - return rejection is not null - ? CliExitCodes.InvalidCommand - : CliExitCodes.FailedToBuildArtifacts; + errorMessage = $"Invalid package '{argument}'. Expected PackageName@Version."; + return false; } - JsonElement export; - try + packageName = argument[..separatorIndex]; + var requestedVersion = argument[(separatorIndex + 1)..]; + if (packageName.Any(char.IsWhiteSpace)) { - _logger.LogDebug("Exporting {Language} API reference for {PackageName}@{PackageVersion} via RPC", language, packageName, packageVersion); - export = await session.RpcClient.ExportApiAsync(language, packageName, packageVersion, cancellationToken); + errorMessage = $"Invalid package '{packageName}'. NuGet package IDs cannot contain whitespace."; + return false; } - catch (RemoteInvocationException ex) - { - InteractionService.DisplayError(ex.Message); - // An unsupported language is a usage error the caller can fix by choosing another - // language, so it is worth distinguishing from the AppHost genuinely falling over. - return IsUnsupportedLanguage(ex) - ? CliExitCodes.InvalidCommand - : CliExitCodes.FailedToBuildArtifacts; - } - catch (NotSupportedException ex) + if (requestedVersion.Any(char.IsWhiteSpace) || + !SemVersion.TryParse(requestedVersion, SemVersionStyles.Any, out var parsedVersion)) { - InteractionService.DisplayError(ex.Message); - return CliExitCodes.InvalidCommand; + errorMessage = $"Invalid version '{requestedVersion}'. Expected an exact NuGet version."; + return false; } - // GetRawText is the document exactly as the language provider wrote it. Re-serializing would - // reshape whitespace and property order for no benefit, and the whole contract here is that - // the payload passes through untouched. - var json = export.GetRawText(); - - if (outputFile is not null) + packageVersion = parsedVersion.ToString(); + var buildMetadataIndex = packageVersion.IndexOf('+', StringComparison.Ordinal); + if (buildMetadataIndex >= 0) { - var outputDir = outputFile.Directory; - if (outputDir is not null && !outputDir.Exists) - { - outputDir.Create(); - } - - await File.WriteAllTextAsync(outputFile.FullName, json, cancellationToken); - InteractionService.DisplaySuccess($"API reference written to {outputFile.FullName}"); - return CliExitCodes.Success; + packageVersion = packageVersion[..buildMetadataIndex]; } - InteractionService.DisplayRawText(json, consoleOverride: ConsoleOutput.Standard); - return CliExitCodes.Success; + return true; } - - // RemoteHost raises NotSupportedException for a generator that cannot export; StreamJsonRpc - // flattens that to a message string, so the type name is the only marker that survives the wire. - private static bool IsUnsupportedLanguage(RemoteInvocationException ex) - => ex.Message.Contains("IApiReferenceExporter", StringComparison.Ordinal) - || ex.Message.Contains("No code generator found for language", StringComparison.Ordinal); } diff --git a/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs index 379e3115fd9..10ba5300625 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs @@ -94,13 +94,6 @@ protected override async Task ExecuteAsync(ParseResult parseResul private async Task GetLanguageInfoAsync(string language, CancellationToken cancellationToken) { - // Every language id starts with the empty string, so an explicitly blank --language would - // otherwise resolve to whichever language was discovered first. - if (string.IsNullOrWhiteSpace(language)) - { - return null; - } - var languages = await _languageDiscovery.GetAvailableLanguagesAsync(cancellationToken); // Match by language ID or code generator name diff --git a/src/Aspire.Cli/Configuration/IntegrationReference.cs b/src/Aspire.Cli/Configuration/IntegrationReference.cs index 6f2e458db1f..79cbe97b65a 100644 --- a/src/Aspire.Cli/Configuration/IntegrationReference.cs +++ b/src/Aspire.Cli/Configuration/IntegrationReference.cs @@ -34,21 +34,6 @@ internal sealed class IntegrationReference /// public bool IsPackageReference => Version is not null; - /// - /// Gets a value indicating whether must resolve to exactly that version. - /// - /// - /// A bare NuGet version is a minimum, not an equality: 13.5.0 means - /// [13.5.0, ) and resolves to the nearest version at or above it, so a version that is - /// missing from the feed silently restores as a later one. Only [13.5.0] pins a single - /// version. Callers that publish artifacts keyed on the requested version — aspire sdk - /// export — set this so an unavailable version fails the restore instead of being described - /// under the wrong number. Everything else keeps the minimum form, which is what lets a shared - /// transitive dependency unify. - /// See https://learn.microsoft.com/nuget/concepts/package-versioning#version-ranges. - /// - public bool RequireExactVersion { get; init; } - /// /// Creates a NuGet package reference. /// @@ -62,46 +47,6 @@ public static IntegrationReference FromPackage(string name, string version) return new IntegrationReference { Name = name, Version = version }; } - /// - /// Creates a NuGet package reference that must restore at exactly . - /// - /// The package name. - /// The NuGet package version. - /// - public static IntegrationReference FromExactPackage(string name, string version) - { - ArgumentException.ThrowIfNullOrEmpty(name); - ArgumentException.ThrowIfNullOrEmpty(version); - - return new IntegrationReference { Name = name, Version = version, RequireExactVersion = true }; - } - - /// - /// Gets the NuGet version range to restore this reference with. - /// - /// - /// Pins the version even when is not set, for callers that - /// decide exactness from context rather than from the reference (for example, restoring Aspire - /// packages from an explicit --source). - /// - /// Either the version as written, or [version] when it has to be pinned. - public string GetRestoreVersionRange(bool forceExact) - { - if (Version is null) - { - throw new InvalidOperationException($"Integration '{Name}' is a project reference and has no version to restore."); - } - - // An explicit range the caller already wrote (`[1.2.3]`, `(1.0,2.0)`) is left alone: wrapping - // it again would produce a syntactically invalid range. - if (!(forceExact || RequireExactVersion) || Version.Length == 0 || Version[0] is '[' or '(') - { - return Version; - } - - return $"[{Version}]"; - } - /// /// Creates a local project reference. /// diff --git a/src/Aspire.Cli/Program.cs b/src/Aspire.Cli/Program.cs index f80776e33cc..0e53283941b 100644 --- a/src/Aspire.Cli/Program.cs +++ b/src/Aspire.Cli/Program.cs @@ -719,12 +719,6 @@ internal static CliExecutionContext BuildCliExecutionContext(bool debugMode, str static bool IsOverride(IdentitySource source) => source is IdentitySource.Environment or IdentitySource.Sidecar; var identityOverridden = IsOverride(channel.Source) || IsOverride(version.Source) || IsOverride(commit.Source) || IsOverride(nugetServiceIndexOverride.Source) || IsOverride(packagesOverride.Source); - // Tracked separately from the aggregate above because callers that need to trust the version - // label cannot use the aggregate: the sidecar is written by every install route, so the - // aggregate is true for an ordinary installed CLI. Only the environment variable makes the - // version a claim this run invented. - var identityVersionForged = version.Source is IdentitySource.Environment; - // A null/whitespace value means "no override"; only materialize a DirectoryInfo when a real // path was supplied. PackagingService validates existence + uniqueness when it consumes this. var identityPackagesDirectory = string.IsNullOrWhiteSpace(packagesOverride.Value) @@ -744,7 +738,6 @@ internal static CliExecutionContext BuildCliExecutionContext(bool debugMode, str nugetServiceIndexOverride: nugetServiceIndexOverride.Value, identityOverridden: identityOverridden, identityPackagesDirectory: identityPackagesDirectory, - identityVersionForged: identityVersionForged, debugMode: debugMode, packagesDirectory: packagesDirectory, aspireHomeDirectory: aspireHomeDirectory); diff --git a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs index cdd39722f78..9f40442407e 100644 --- a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs +++ b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs @@ -171,9 +171,7 @@ public IntegrationPackageProbeManifest CreatePackageProbeManifest() { Name = Path.GetFileNameWithoutExtension(entry.RelativePath), Culture = TryGetSatelliteCulture(entry), - Path = entry.SourcePath, - PackageId = entry.PackageId, - PackageVersion = entry.PackageVersion + Path = entry.SourcePath }); } diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index aef3c452008..0310505326a 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; @@ -31,9 +30,6 @@ internal sealed class DotNetBasedAppHostServerProject : IAppHostServerProject internal const string TargetFramework = "net10.0"; public const string BuildFolder = "build"; private const string AssemblyName = "AppHostServer"; - private const string PackageProbeSourcesFileName = "package-probe-sources.txt"; - private const string PackageProbeMetadataFileName = "package-probe-metadata.txt"; - private const string PackageProbeTargetsFileName = "package-probe-targets.txt"; private readonly string _projectModelPath; private readonly string _appPath; @@ -46,11 +42,6 @@ internal sealed class DotNetBasedAppHostServerProject : IAppHostServerProject private readonly IEnvironment _environment; private readonly ILogger _logger; private readonly string? _logFilePath; - private string? _integrationProbeManifestPath; - - // Boxed so "not read yet" and "read, and there is no answer" stay distinguishable without - // re-parsing eng/Versions.props on every lookup. - private StrongBox? _repositoryVersionPrefix; public DotNetBasedAppHostServerProject( string appPath, @@ -176,7 +167,7 @@ private XDocument CreateProjectFile(IEnumerable integratio // Add project references for Aspire.Hosting.* packages, NuGet for others var projectRefGroup = new XElement("ItemGroup"); var addedProjects = new HashSet(StringComparer.OrdinalIgnoreCase); - var otherPackages = new List(); + var otherPackages = new List<(string Name, string Version)>(); foreach (var integration in integrations) { @@ -190,37 +181,18 @@ private XDocument CreateProjectFile(IEnumerable integratio new XElement("IsAspireProjectResource", "false"))); } } - else if (integration.Name.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase)) + // An exact range is an explicit request to restore that package, used by sdk export so + // the document cannot be labelled with a package version while describing checkout code. + else if (integration.Name.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase) && + !IsExactVersionRange(integration.Version)) { - if (GetLocalProjectSubstitution(integration.Name) is { } substitution) - { - if (addedProjects.Add(integration.Name)) - { - projectRefGroup.Add(new XElement("ProjectReference", - new XAttribute("Include", substitution.ProjectPath), - new XElement("IsAspireProjectResource", "false"))); - } - } - else if (integration.RequireExactVersion) + var projectPath = Path.Combine(_repoRoot, "src", integration.Name, $"{integration.Name}.csproj"); + if (File.Exists(projectPath) && addedProjects.Add(integration.Name)) { - // A first-party name does not mean this checkout can supply it. Dropping the - // reference made `sdk export --package Aspire.Hosting.DoesNotExist@13.5.0-dev` - // scan clean and publish an empty module under a package id that has never - // existed, so a caller that demands an exact version gets a real package - // reference instead and the restore fails (NU1101) as it should. - if (integration.Version is null) - { - throw new InvalidOperationException($"Integration '{integration.Name}' is neither a project reference nor a package reference (both Version and ProjectPath are null)."); - } - otherPackages.Add(integration); + projectRefGroup.Add(new XElement("ProjectReference", + new XAttribute("Include", projectPath), + new XElement("IsAspireProjectResource", "false"))); } - - // Everything else keeps dropping the reference. Only `sdk export` asks for exactness, - // and only it names the package explicitly; `aspire run`, `sdk dump`, and `sdk - // generate` take their integrations from aspire.config.json, where a version-less - // entry resolves to this CLI's identity (`13.5.0-dev` in a checkout). Restoring that - // as a package could never succeed, so failing here would turn one unavailable - // integration into a build failure for the whole AppHost. } else { @@ -228,7 +200,7 @@ private XDocument CreateProjectFile(IEnumerable integratio { throw new InvalidOperationException($"Integration '{integration.Name}' is neither a project reference nor a package reference (both Version and ProjectPath are null)."); } - otherPackages.Add(integration); + otherPackages.Add((integration.Name, integration.Version)); } } @@ -248,14 +220,10 @@ private XDocument CreateProjectFile(IEnumerable integratio if (otherPackages.Count > 0) { - // This project always gets a generated Directory.Packages.props that turns central package - // management on, so an inline Version attribute is rejected with NU1008. VersionOverride is - // the CPM-sanctioned way to pin a single reference, and it lets us scan an integration that - // the repo's Directory.Packages.props has no PackageVersion entry for. doc.Root!.Add(new XElement("ItemGroup", otherPackages.Select(p => new XElement("PackageReference", new XAttribute("Include", p.Name), - new XAttribute("VersionOverride", p.GetRestoreVersionRange(forceExact: false)))))); + new XAttribute("Version", p.Version))))); } // Add imports for in-repo AppHost building @@ -289,30 +257,16 @@ private XDocument CreateProjectFile(IEnumerable integratio // Disable Aspire SDK code generation doc.Root!.Add(new XElement("Target", new XAttribute("Name", "_CSharpWriteHostProjectMetadataSources"))); doc.Root!.Add(new XElement("Target", new XAttribute("Name", "_CSharpWriteProjectMetadataSources"))); - doc.Root!.Add( - new XElement("Target", - new XAttribute("Name", "_WriteAspirePackageProbeManifestInputs"), - new XAttribute("AfterTargets", "Build"), - new XAttribute("DependsOnTargets", "ResolveLockFileCopyLocalFiles"), - new XElement("WriteLinesToFile", - new XAttribute("File", Path.Combine(_projectModelPath, PackageProbeSourcesFileName)), - new XAttribute("Lines", "@(ReferenceCopyLocalPaths->'%(FullPath)')"), - new XAttribute("Overwrite", "true"), - new XAttribute("WriteOnlyWhenDifferent", "true")), - new XElement("WriteLinesToFile", - new XAttribute("File", Path.Combine(_projectModelPath, PackageProbeMetadataFileName)), - new XAttribute("Lines", "@(ReferenceCopyLocalPaths->'%(NuGetPackageId)|%(NuGetPackageVersion)|%(AssetType)')"), - new XAttribute("Overwrite", "true"), - new XAttribute("WriteOnlyWhenDifferent", "true")), - new XElement("WriteLinesToFile", - new XAttribute("File", Path.Combine(_projectModelPath, PackageProbeTargetsFileName)), - new XAttribute("Lines", "@(ReferenceCopyLocalPaths->'%(DestinationSubDirectory)%(Filename)%(Extension)')"), - new XAttribute("Overwrite", "true"), - new XAttribute("WriteOnlyWhenDifferent", "true")))); return doc; } + private static bool IsExactVersionRange(string? version) + => version is { Length: > 2 } && + version[0] == '[' && + version[^1] == ']' && + !version.Contains(','); + /// /// Scaffolds the project files. /// @@ -514,8 +468,6 @@ public async Task PrepareAsync( NeedsCodeGeneration: false); } - await WriteIntegrationProbeManifestAsync(cancellationToken).ConfigureAwait(false); - return new AppHostServerPrepareResult( Success: true, Output: buildOutput, @@ -526,134 +478,6 @@ public async Task PrepareAsync( /// public string GetInstanceIdentifier() => GetProjectFilePath(); - /// - /// - /// - /// This is the same decision makes, kept in one place so a - /// caller asking "will my requested version survive?" cannot drift from what the generated - /// project actually does. Only first-party Aspire.Hosting.* packages live under - /// src/, so a third-party integration is always restored from a feed even here. - /// - /// - /// The name is matched case-insensitively, because a NuGet package id is - /// () - /// while the filesystem this resolves through is not on Linux. Probing the caller's spelling - /// directly meant aspire.hosting.redis found nothing there and src/Aspire.Hosting.Redis - /// on macOS and Windows, so how a package was spelled decided whether the checkout was used at - /// all — and callers that publish version-keyed artifacts saw no substitution to guard against. - /// The returned path is always the on-disk spelling so the generated project reference and the - /// caller's check name the same project. - /// - /// - public LocalProjectSubstitution? GetLocalProjectSubstitution(string packageName) - { - if (!packageName.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - var srcPath = Path.Combine(_repoRoot, "src"); - if (!Directory.Exists(srcPath)) - { - return null; - } - - // The directory listing settles the spelling on every platform. Probing - // Path.Combine(src, packageName) instead would hand back the caller's spelling wherever - // File.Exists is case-insensitive, so the same request produced two different project paths - // depending on the filesystem. Enumerate and compare rather than passing the caller's name - // as a search pattern, so a package id that happens to contain a wildcard cannot match a - // directory it does not name. - // - // Enumerating can throw where the old File.Exists probe could not, and this runs on the - // `aspire run` path via CreateProjectFile, so an unreadable or concurrently removed src/ - // reports "no substitution" the same way GetRepositoryVersionPrefix does rather than - // costing the caller its scanner. - try - { - foreach (var directory in Directory.EnumerateDirectories(srcPath)) - { - var canonicalName = Path.GetFileName(directory); - if (!string.Equals(canonicalName, packageName, StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - var projectPath = Path.Combine(directory, $"{canonicalName}.csproj"); - return File.Exists(projectPath) - ? new LocalProjectSubstitution(projectPath, GetRepositoryVersionPrefix()) - : null; - } - } - catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) - { - return null; - } - - return null; - } - - /// - /// Reads the Major.Minor.Patch this checkout builds from eng/Versions.props, or - /// when it cannot be established. - /// - /// - /// - /// The repository states its version line as three properties that VersionPrefix is - /// composed from: - /// - /// <MajorVersion>13</MajorVersion> - /// <MinorVersion>5</MinorVersion> - /// <PatchVersion>0</PatchVersion> - /// <VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix> - /// - /// VersionPrefix itself is read as the unexpanded MSBuild expression, so the three parts - /// are read directly. The prerelease suffix (-preview.1.25366.3) is assigned by Arcade at - /// build time and is not in the checkout, which is why only the prefix can be established here. - /// - /// - /// Any failure returns rather than throwing: this only informs callers - /// that need provenance, and no other caller should lose a scanner over an unreadable file. - /// - /// - private string? GetRepositoryVersionPrefix() - { - if (_repositoryVersionPrefix is { } cached) - { - return cached.Value; - } - - _repositoryVersionPrefix = ReadRepositoryVersionPrefix(_repoRoot); - return _repositoryVersionPrefix.Value; - } - - private static StrongBox ReadRepositoryVersionPrefix(string repoRoot) - { - try - { - var versionsPropsPath = Path.Combine(repoRoot, "eng", "Versions.props"); - if (!File.Exists(versionsPropsPath)) - { - return new StrongBox(null); - } - - var doc = XDocument.Load(versionsPropsPath); - - var major = doc.Descendants("MajorVersion").FirstOrDefault()?.Value; - var minor = doc.Descendants("MinorVersion").FirstOrDefault()?.Value; - var patch = doc.Descendants("PatchVersion").FirstOrDefault()?.Value; - - return new StrongBox( - string.IsNullOrWhiteSpace(major) || string.IsNullOrWhiteSpace(minor) || string.IsNullOrWhiteSpace(patch) - ? null - : $"{major.Trim()}.{minor.Trim()}.{patch.Trim()}"); - } - catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or System.Xml.XmlException) - { - return new StrongBox(null); - } - } - /// public async Task RunAsync( int hostPid, @@ -701,19 +525,6 @@ public async Task RunAsync( // for the dashboard to resolve static web assets correctly startInfo.Environment[KnownAspNetCoreConfigNames.Environment] = "Development"; - if (_integrationProbeManifestPath is not null) - { - _logger.LogDebug( - "Setting {EnvironmentVariable} to {Path}", - KnownConfigNames.IntegrationProbeManifestPath, - _integrationProbeManifestPath); - startInfo.Environment[KnownConfigNames.IntegrationProbeManifestPath] = _integrationProbeManifestPath; - } - else - { - startInfo.Environment.Remove(KnownConfigNames.IntegrationProbeManifestPath); - } - // Wire WithTerminal() for guest/polyglot AppHosts running from the repo. The // generated AppHostServer references Aspire.Hosting from the repo and DCP resolves // the terminal host via ASPIRE_TERMINAL_HOST_PATH or assembly metadata. No per-RID @@ -798,130 +609,6 @@ void OnStderr(string line) return new AppHostServerRunResult(_socketPath, outputCollector, execution); } - private async Task WriteIntegrationProbeManifestAsync(CancellationToken cancellationToken) - { - var sourcesPath = Path.Combine(_projectModelPath, PackageProbeSourcesFileName); - var metadataPath = Path.Combine(_projectModelPath, PackageProbeMetadataFileName); - var targetsPath = Path.Combine(_projectModelPath, PackageProbeTargetsFileName); - - if (!File.Exists(sourcesPath) || !File.Exists(metadataPath) || !File.Exists(targetsPath)) - { - _integrationProbeManifestPath = null; - return; - } - - var sourcePaths = await File.ReadAllLinesAsync(sourcesPath, cancellationToken).ConfigureAwait(false); - var metadataLines = await File.ReadAllLinesAsync(metadataPath, cancellationToken).ConfigureAwait(false); - var targetPaths = await File.ReadAllLinesAsync(targetsPath, cancellationToken).ConfigureAwait(false); - if (sourcePaths.Length != metadataLines.Length || sourcePaths.Length != targetPaths.Length) - { - throw new InvalidOperationException( - $"Package probe manifest inputs are inconsistent. Sources: {sourcePaths.Length}, metadata: {metadataLines.Length}, targets: {targetPaths.Length}."); - } - - var managedAssemblies = new List(); - var nativeLibraries = new List(); - - for (var i = 0; i < sourcePaths.Length; i++) - { - cancellationToken.ThrowIfCancellationRequested(); - - var metadata = ParsePackageProbeMetadata(metadataLines[i]); - if (string.IsNullOrWhiteSpace(metadata.PackageId) || - string.IsNullOrWhiteSpace(metadata.PackageVersion)) - { - continue; - } - - var sourcePath = sourcePaths[i]; - var targetPath = NormalizePackageProbeTargetPath(targetPaths[i], sourcePath); - if (string.Equals(metadata.AssetType, "native", StringComparison.OrdinalIgnoreCase)) - { - nativeLibraries.Add(new IntegrationPackageNativeLibrary - { - FileName = Path.GetFileName(targetPath), - Path = sourcePath - }); - continue; - } - - if (!sourcePath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - managedAssemblies.Add(new IntegrationPackageManagedAssembly - { - Name = Path.GetFileNameWithoutExtension(targetPath), - Culture = TryGetSatelliteCulture(targetPath, metadata.AssetType), - Path = sourcePath, - PackageId = metadata.PackageId, - PackageVersion = metadata.PackageVersion - }); - } - - if (managedAssemblies.Count == 0 && nativeLibraries.Count == 0) - { - _integrationProbeManifestPath = null; - return; - } - - _integrationProbeManifestPath = Path.Combine(_projectModelPath, IntegrationPackageProbeManifest.FileName); - await IntegrationPackageProbeManifest.WriteAsync( - _integrationProbeManifestPath, - IntegrationPackageProbeManifest.Create(managedAssemblies, nativeLibraries), - cancellationToken).ConfigureAwait(false); - } - - private static PackageProbeMetadata ParsePackageProbeMetadata(string line) - { - // Written from ReferenceCopyLocalPaths as: - // Contoso.Aspire.MetaPackage|1.2.3|runtime - // Empty fields are possible for project references; those entries are intentionally - // ignored because the probe manifest only preserves NuGet package ownership. - var parts = line.Split('|'); - if (parts.Length != 3) - { - throw new InvalidOperationException($"Package probe manifest metadata line has an unexpected format: '{line}'."); - } - - return new PackageProbeMetadata( - NormalizeOptionalValue(parts[0]), - NormalizeOptionalValue(parts[1]), - NormalizeOptionalValue(parts[2])); - } - - private static string NormalizePackageProbeTargetPath(string targetPath, string sourcePath) - { - if (string.IsNullOrWhiteSpace(targetPath)) - { - return Path.GetFileName(sourcePath); - } - - return targetPath.Replace('\\', '/').TrimStart('/'); - } - - private static string? TryGetSatelliteCulture(string relativePath, string? assetType) - { - if (!string.Equals(assetType, "resources", StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - var directoryName = Path.GetDirectoryName(relativePath.Replace('/', Path.DirectorySeparatorChar)); - if (string.IsNullOrWhiteSpace(directoryName)) - { - return null; - } - - return directoryName.Replace('\\', '/').Trim('/'); - } - - private static string? NormalizeOptionalValue(string value) - => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); - - private sealed record PackageProbeMetadata(string? PackageId, string? PackageVersion, string? AssetType); - private static string? FindNuGetConfig(string workingDirectory) { try diff --git a/src/Aspire.Cli/Projects/IAppHostServerProject.cs b/src/Aspire.Cli/Projects/IAppHostServerProject.cs index 4fbcb761233..baf287db6eb 100644 --- a/src/Aspire.Cli/Projects/IAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/IAppHostServerProject.cs @@ -136,17 +136,4 @@ Task RunAsync( /// /// A path that uniquely identifies this AppHost. string GetInstanceIdentifier(); - - /// - /// Gets the local project this server builds in place of , or - /// when the package is restored from a feed at the requested version. - /// - /// - /// Only the repository development server substitutes projects for packages, so every other - /// implementation keeps this default. Callers that publish artifacts keyed on a package version - /// need to know the difference: a substituted project carries the checkout's API surface rather - /// than the surface of the version that was asked for. - /// - /// The package name the caller asked to restore. - LocalProjectSubstitution? GetLocalProjectSubstitution(string packageName) => null; } diff --git a/src/Aspire.Cli/Projects/LocalProjectSubstitution.cs b/src/Aspire.Cli/Projects/LocalProjectSubstitution.cs deleted file mode 100644 index a67da58f626..00000000000 --- a/src/Aspire.Cli/Projects/LocalProjectSubstitution.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Aspire.Cli.Projects; - -/// -/// A package an AppHost server builds from local source instead of restoring from a feed. -/// -/// -/// This only happens in repository development mode. It matters to callers that publish artifacts -/// keyed on a package version, because the substituted project carries whatever the checkout -/// currently contains rather than the version that was requested. -/// -/// The project built in place of the package. -/// -/// The Major.Minor.Patch the checkout produces, read from the checkout itself, or -/// when it cannot be established. This is deliberately not the running CLI's -/// reported version: that value is overrideable (ASPIRE_CLI_VERSION, the install sidecar), so -/// checking a requested version against it alone lets a caller name local source whatever they like. -/// It is a prefix rather than a full version because the prerelease suffix is assigned at build time -/// by Arcade and is not recorded in the checkout. -/// -internal sealed record LocalProjectSubstitution(string ProjectPath, string? CheckoutVersionPrefix); diff --git a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs index 661a83a8896..5c8799ead3a 100644 --- a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs +++ b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs @@ -280,10 +280,7 @@ private static void AppendRestoreContextOnFailure( if (packageRefs.Count > 0) { - // Show the range restore was actually given, not the raw version: `--source` and - // exact references both pin to `[x.y.z]`, and a reader chasing a resolution failure - // needs to see that the request was an equality rather than a minimum. - var preview = packageRefs.Take(5).Select(r => $"{r.Name} {GetRestoreVersion(r, hasOverride)}"); + var preview = packageRefs.Take(5).Select(static r => $"{r.Name} {r.Version}"); output.AppendError($" packages: {string.Join(", ", preview)}{(packageRefs.Count > 5 ? $", … (+{packageRefs.Count - 5} more)" : string.Empty)}"); } } @@ -301,7 +298,7 @@ private async Task RestoreNuGetPackagesAsync( var useExactPackageVersions = !string.IsNullOrWhiteSpace(packageSourceOverride); var packages = packageRefs - .Select(r => (r.Name, Version: GetRestoreVersion(r, useExactPackageVersions))) + .Select(r => (r.Name, Version: GetRestoreVersion(r.Name, r.Version!, useExactPackageVersions))) .ToList(); using var temporaryNuGetConfig = await TryCreateTemporaryNuGetConfigAsync(requestedChannel, packageSourceOverride, cancellationToken); var sources = await GetNuGetSourcesAsync(requestedChannel, packageSourceOverride, cancellationToken); @@ -493,7 +490,7 @@ internal static string GenerateIntegrationProjectFile( } return new XElement("PackageReference", new XAttribute("Include", p.Name), - new XAttribute("Version", GetRestoreVersion(p, useExactPackageVersions))); + new XAttribute("Version", GetRestoreVersion(p.Name, p.Version, useExactPackageVersions))); }))); } @@ -906,15 +903,15 @@ private async Task> GetExplicitRestoreChannelsAsync( return channels.Where(c => c.Type == PackageChannelType.Explicit).ToArray(); } - private static string GetRestoreVersion(IntegrationReference reference, bool useExactPackageVersions) + private static string GetRestoreVersion(string packageName, string version, bool useExactPackageVersions) { - // The `--source` case pins Aspire packages so a private hive cannot be topped up from a - // public feed. A reference that already demands exactness pins regardless of package name, - // which is what lets `sdk export` restore a third-party integration at exactly one version. - var shouldUseExactAspirePackageVersion = useExactPackageVersions - && reference.Name.StartsWith("Aspire", StringComparison.OrdinalIgnoreCase); + var shouldUseExactAspirePackageVersion = useExactPackageVersions && packageName.StartsWith("Aspire", StringComparison.OrdinalIgnoreCase); + if (!shouldUseExactAspirePackageVersion || version.Length == 0 || version[0] is '[' or '(') + { + return version; + } - return reference.GetRestoreVersionRange(forceExact: shouldUseExactAspirePackageVersion); + return $"[{version}]"; } // Display-safe form of a NuGet source used in user-visible error footers. Delegates to the diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj b/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj index 473ccd19845..a16b9c5e583 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj @@ -37,7 +37,6 @@ - diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs deleted file mode 100644 index 57e0a6d03d8..00000000000 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsContextCompatibility.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using Aspire.TypeSystem; - -namespace Aspire.Hosting.CodeGeneration.TypeScript; - -/// -/// Reads members that were added after the shared contract's frozen -/// strong-name version, in a way that degrades instead of failing when the loaded contract predates -/// them. -/// -/// -/// -/// Aspire.TypeSystem is force-shared from the apphost server's default -/// and freezes its AssemblyVersion at -/// 13.4.5.0 (see src/Aspire.TypeSystem/Aspire.TypeSystem.csproj and -/// src/Aspire.Hosting.RemoteHost/IntegrationLoadContext.cs), so an already-shipped CLI binds -/// a newer SDK's code generation assembly against its own older copy of the contract. Binding -/// succeeds; the newer members simply are not there. -/// -/// -/// Splitting export onto only protects type -/// loading — a type whose interface list or signatures name a missing type is dropped, and the code -/// generator survives. It does nothing for a method body that names a missing member: the -/// JIT resolves a method's tokens when that method first runs, so a direct read of a newer property -/// from the generator path throws at generation time and takes -/// ordinary TypeScript generation down with it. Probing once and keeping every direct read behind -/// that probe, in a method the JIT is not allowed to inline into its caller, is what keeps the -/// generator path free of that hard bind. -/// -/// -internal static class AtsContextCompatibility -{ - // nameof is a compile-time constant, so the probe itself carries no reference to the member and - // is safe to evaluate against a contract that predates it. - private static readonly bool s_exposesCapabilityExportingAssemblyNames = - typeof(AtsContext).GetProperty(nameof(AtsContext.CapabilityExportingAssemblyNames)) is not null; - - /// - /// Gets the assembly that exported , when the loaded contract - /// records exporting assemblies at all. - /// - /// The ATS context to read. - /// The capability whose exporting assembly is wanted. - /// The exporting assembly name, when one was recorded. - /// - /// when the loaded contract exposes the mapping and it names - /// ; otherwise , which callers are - /// expected to answer with their own ownership fallback. - /// - public static bool TryGetCapabilityExportingAssemblyName( - AtsContext context, - string capabilityId, - [NotNullWhen(true)] out string? exportingAssemblyName) - { - if (s_exposesCapabilityExportingAssemblyNames) - { - return ReadCapabilityExportingAssemblyName(context, capabilityId, out exportingAssemblyName); - } - - exportingAssemblyName = null; - return false; - } - - // NoInlining is load-bearing, not a hint: inlining this body into its caller would move the - // member reference back onto a method the generator path always runs, which is exactly the hard - // bind the probe exists to avoid. - [MethodImpl(MethodImplOptions.NoInlining)] - private static bool ReadCapabilityExportingAssemblyName( - AtsContext context, - string capabilityId, - [NotNullWhen(true)] out string? exportingAssemblyName) - => context.CapabilityExportingAssemblyNames.TryGetValue(capabilityId, out exportingAssemblyName); -} diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs index 43b4ea34cd6..37d9faf387b 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs @@ -30,12 +30,6 @@ namespace Aspire.Hosting.CodeGeneration.TypeScript; /// , so the generator survives and only /// this type disappears. /// -/// -/// The split covers type loading only. A method body on the generation path that names a newer -/// shared-contract member is a separate hard bind that no type split can absorb, because -/// the JIT resolves a method's tokens when that method first runs; see -/// for how those reads are kept out of the generator path. -/// /// internal sealed class AtsTypeScriptApiReferenceExporter : IApiReferenceExporter { @@ -43,7 +37,10 @@ internal sealed class AtsTypeScriptApiReferenceExporter : IApiReferenceExporter public string Language => "TypeScript"; /// - public JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options) + public JsonElement ExportApi( + AtsContext context, + ApiReferenceExportOptions options, + CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(options); @@ -54,7 +51,8 @@ public JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions optio var projector = new TypeScriptApiProjector(context); var model = projector.BuildApiModel( new TypeScriptApiPackageIdentity(options.PackageName, options.PackageVersion), - options.ExportingAssemblyNames); + options.ExportingAssemblyNames, + cancellationToken); // JsonDocument.Parse + Clone rather than JsonSerializer, because this assembly is // AOT-compatible and the serializer's reflection-based overloads are not. diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs index a2ae70e3e49..73b904ae962 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs @@ -18,9 +18,6 @@ namespace Aspire.Hosting.CodeGeneration.TypeScript; /// internal static class TypeScriptApiExportWriter { - /// The schema version emitted by this writer. - public const int SchemaVersion = TypeScriptApiProjector.ExportSchemaVersion; - public static JsonObject Write(TypeScriptApiModel model) { ArgumentNullException.ThrowIfNull(model); @@ -46,6 +43,11 @@ public static JsonObject Write(TypeScriptApiModel model) { ["schemaVersion"] = model.SchemaVersion, ["language"] = model.Language, + ["generator"] = new JsonObject + { + ["name"] = model.Generator.Name, + ["version"] = model.Generator.Version + }, ["package"] = new JsonObject { ["name"] = model.Package.Name, diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs index 8e4b60224f4..b5823087517 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs @@ -42,6 +42,13 @@ internal enum TypeScriptApiItemKind /// The exact package version, for example 13.5.0. internal sealed record TypeScriptApiPackageIdentity(string Name, string Version); +/// +/// Identifies the code generator that produced a canonical export. +/// +/// The code-generation assembly name. +/// The code-generation assembly informational version. +internal sealed record TypeScriptApiGeneratorIdentity(string Name, string Version); + /// /// A single parameter of a resolved TypeScript signature. /// @@ -206,6 +213,9 @@ internal sealed record TypeScriptApiModel /// Gets the export language, always typescript. public required string Language { get; init; } + /// Gets the code generator identity that produced this export. + public required TypeScriptApiGeneratorIdentity Generator { get; init; } + /// Gets the exact package identity this export was produced for. public required TypeScriptApiPackageIdentity Package { get; init; } diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 66124d411e6..6d5ffa34fa6 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Globalization; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; using Aspire.Shared.CodeGeneration; @@ -41,6 +41,8 @@ internal sealed partial class TypeScriptApiProjector /// private const string RuntimeDeclarationId = "aspire:runtime:base"; + private static readonly TypeScriptApiGeneratorIdentity s_generatorIdentity = CreateGeneratorIdentity(); + /// The symbol names already declares. private static readonly HashSet s_runtimeDeclaredNames = new(StringComparer.Ordinal) { @@ -405,12 +407,15 @@ private string ResolveTypeClassReturnType(BuilderModel builder, AtsCapabilityInf /// through the referenced-type closure: they contribute declaration fragments so the export /// type-checks, but they must not produce documentation pages here. /// + /// A token to cancel the export between projected items. internal TypeScriptApiModel BuildApiModel( TypeScriptApiPackageIdentity package, - IReadOnlyCollection ownedAssemblyNames) + IReadOnlyCollection ownedAssemblyNames, + CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(package); ArgumentNullException.ThrowIfNull(ownedAssemblyNames); + cancellationToken.ThrowIfCancellationRequested(); var owned = new HashSet(ownedAssemblyNames, StringComparer.OrdinalIgnoreCase); @@ -427,6 +432,7 @@ internal TypeScriptApiModel BuildApiModel( foreach (var builderModel in _resolved.Builders.OrderBy(b => b.BuilderClassName, StringComparer.Ordinal)) { + cancellationToken.ThrowIfCancellationRequested(); var (item, builderDeclarations) = ProjectBuilder(package, builderModel, owned); foreach (var declaration in builderDeclarations) @@ -442,6 +448,7 @@ internal TypeScriptApiModel BuildApiModel( foreach (var entryPoint in _resolved.ClientMethods.OrderBy(c => c.MethodName, StringComparer.Ordinal)) { + cancellationToken.ThrowIfCancellationRequested(); if (!owned.Contains(GetCapabilityOwningAssemblyName(entryPoint))) { continue; @@ -454,6 +461,7 @@ internal TypeScriptApiModel BuildApiModel( .Where(e => e.TypeId != InputTypeTypeId) .OrderBy(e => e.Name, StringComparer.Ordinal)) { + cancellationToken.ThrowIfCancellationRequested(); var (item, declaration) = ProjectEnum(enumType); declarations[declaration.Id] = declaration; @@ -468,6 +476,7 @@ internal TypeScriptApiModel BuildApiModel( .Where(d => d.TypeId != InteractionInputTypeId) .OrderBy(d => d.TypeId, StringComparer.Ordinal)) { + cancellationToken.ThrowIfCancellationRequested(); var (item, declaration) = ProjectDto(dtoType); declarations[declaration.Id] = declaration; @@ -485,6 +494,7 @@ internal TypeScriptApiModel BuildApiModel( // package would document options interfaces belonging to its dependencies. foreach (var (interfaceName, optionalParams) in _optionsInterfacesToGenerate.OrderBy(kvp => kvp.Key, StringComparer.Ordinal)) { + cancellationToken.ThrowIfCancellationRequested(); var owningAssemblyName = _optionsInterfaceOwningAssemblies.GetValueOrDefault(interfaceName, package.Name); var (item, declaration) = ProjectOptionsInterface(owningAssemblyName, interfaceName, optionalParams); @@ -515,6 +525,7 @@ internal TypeScriptApiModel BuildApiModel( foreach (var typeId in _resolved.HandleTypeIds.OrderBy(id => id, StringComparer.Ordinal)) { + cancellationToken.ThrowIfCancellationRequested(); var wrapperClassName = _wrapperClassNames.GetValueOrDefault(typeId); var owningAssembly = GetTypeOwningAssemblyName(typeId); @@ -587,12 +598,23 @@ internal TypeScriptApiModel BuildApiModel( { SchemaVersion = ExportSchemaVersion, Language = "typescript", + Generator = s_generatorIdentity, Package = package, Modules = [module], Declarations = [.. declarations.Values.OrderBy(d => d.Id, StringComparer.Ordinal)] }; } + private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() + { + var assembly = typeof(TypeScriptApiProjector).Assembly; + var version = assembly.GetCustomAttribute()?.InformationalVersion + ?? throw new InvalidOperationException( + $"The '{assembly.GetName().Name}' assembly has no informational version."); + + return new TypeScriptApiGeneratorIdentity(assembly.GetName().Name!, version); + } + /// /// Projects one builder into an optional documented item plus the declaration fragments it /// contributes. @@ -790,7 +812,7 @@ private TypeScriptApiMember ProjectMethod( { Id = $"method:{ownerName}.{capability.MethodName}", Kind = TypeScriptApiItemKind.Method, - Name = capability.MethodName, + Name = signature.MethodName, Declaration = signature.Declaration, Summary = capability.Documentation?.Summary, Remarks = capability.Documentation?.Remarks, @@ -864,15 +886,16 @@ private TypeScriptApiItem ProjectEntryPoint(TypeScriptApiPackageIdentity package { _ = package; var signature = ResolveEntryPointSignature(capability); + var owningAssemblyName = GetCapabilityOwningAssemblyName(capability); return new TypeScriptApiItem { - Id = $"method:{capability.MethodName}", + Id = $"entrypoint:{owningAssemblyName}:{signature.MethodName}", TypeId = capability.CapabilityId, Kind = TypeScriptApiItemKind.Method, - Name = capability.MethodName, + Name = signature.MethodName, Declaration = $"function {signature.Declaration}", - OwningAssemblyName = GetCapabilityOwningAssemblyName(capability), + OwningAssemblyName = owningAssemblyName, Summary = capability.Documentation?.Summary, Remarks = capability.Documentation?.Remarks, Members = [] @@ -1153,9 +1176,7 @@ private static string GetOwningAssemblyName(string atsId, string? clrAssemblyNam /// /// /// This mirrors AtsContextFilter.IsCapabilityOwnedBySelectedAssembly. The two must agree, - /// or the exporter would document symbols the filter excluded, or drop symbols it kept. A CLI - /// that predates runs the pre-map - /// filter as well, so both sides fall back to reflection together and still agree. + /// or the exporter would document symbols the filter excluded, or drop symbols it kept. /// private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) => GetCapabilityOwningAssemblyName(_resolved.Context, capability); @@ -1167,14 +1188,6 @@ private string GetCapabilityOwningAssemblyName(AtsCapabilityInfo capability) /// private static string GetCapabilityOwningAssemblyName(AtsContext context, AtsCapabilityInfo capability) { - // Read through the compatibility shim rather than off the context directly: this method runs - // on the ordinary generation path, and a direct read hard-binds it to a contract member an - // already-shipped CLI does not have. See AtsContextCompatibility for the failure it avoids. - if (AtsContextCompatibility.TryGetCapabilityExportingAssemblyName(context, capability.CapabilityId, out var exportingAssemblyName)) - { - return exportingAssemblyName; - } - if (context.Methods.TryGetValue(capability.CapabilityId, out var method)) { return method.DeclaringType?.Assembly.GetName().Name ?? string.Empty; @@ -1673,103 +1686,15 @@ internal static string ToPascalCase(string name) } /// - /// Gets the options interface name for a method owned by . + /// Gets the options interface name for a method. /// Strips any type prefix (e.g., "TypeName.methodName" -> "MethodName"). /// - /// - /// - /// First-party Aspire names stay unqualified unless the checked-in shipped ATS surface already - /// has a real cross-package collision for that unqualified name. That preserves the old public - /// names for the unique option bags while still making the known collision groups a function of - /// the capability alone. Third-party assemblies are always qualified because their package - /// exports are produced one at a time and cannot rely on this repository's collision guard. - /// - /// - /// The core hosting package keeps unqualified names even inside a collision group. Other - /// packages in those groups carry an encoding of their full assembly name, so - /// Aspire.Hosting.Azure.EventHubs yields - /// Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions. The TypeScript - /// API compatibility path guards this selective list so a new cross-package collision cannot - /// silently preserve an unsafe unqualified name. - /// - /// - internal static string GetOptionsInterfaceName(string methodName, string owningAssemblyName) + internal static string GetOptionsInterfaceName(string methodName) { - var unqualifiedName = TypeScriptOptionsInterfaceNaming.GetUnqualifiedOptionsInterfaceName(methodName); - if (string.IsNullOrEmpty(owningAssemblyName) || - string.Equals(owningAssemblyName, AtsConstants.AspireHostingAssembly, StringComparison.Ordinal) || - !TypeScriptOptionsInterfaceNaming.RequiresPackageQualifier(unqualifiedName, owningAssemblyName)) - { - return unqualifiedName; - } - - // '$' terminates the qualifier. Concatenating two individually injective encodings is not - // injective at the seam -- assembly `Contoso` with method `fooBar` and assembly `ContosoFoo` - // with method `bar` both yield ContosoFooBarOptions -- and the collision guard only inspects - // unqualified names, so two package exports could contribute conflicting declarations under - // one symbol. Every non-alphanumeric code unit in the qualifier is escaped, so '$' can never - // occur inside it: the first '$' is always the seam, whatever the method name contains. - return $"{GetOptionsInterfaceQualifier(owningAssemblyName)}{OptionsInterfaceQualifierSeparator}{unqualifiedName}"; - } - - private const string OptionsInterfaceQualifierSeparator = "$"; - - /// - /// Derives the name-space prefix an assembly's options interfaces carry when their unqualified - /// names are in a known collision group. - /// - /// - /// - /// The encoding has to be injective. A per-package export sees only its own assemblies, so it - /// cannot detect that some other package would produce the same qualifier and disambiguate the - /// way full generation could. Two assemblies that collide here would emit conflicting options - /// interfaces that fail to compile once both package exports are concatenated, which is the - /// failure this qualifier exists to prevent. Simply dropping separators is not injective: - /// Contoso.Foo.Bar and Contoso.FooBar would both yield ContosoFooBar. - /// - /// - /// So every non-alphanumeric UTF-16 code unit is encoded rather than removed, and the full - /// assembly name is kept. Each escape is _xNNNN_ with a terminator, so - /// Contoso.Foo-Bar cannot alias Contoso.Foo.x2DBar, and U+0123 followed - /// by 4 cannot alias U+1234. A leading digit is escaped too because TypeScript - /// identifiers may not start with one. - /// - /// - private static string GetOptionsInterfaceQualifier(string owningAssemblyName) - { - if (string.IsNullOrEmpty(owningAssemblyName) || - string.Equals(owningAssemblyName, AtsConstants.AspireHostingAssembly, StringComparison.Ordinal)) - { - return string.Empty; - } - - var qualifier = new StringBuilder(owningAssemblyName.Length); - for (var i = 0; i < owningAssemblyName.Length; i++) - { - var character = owningAssemblyName[i]; - if (char.IsAsciiLetter(character) || (i > 0 && char.IsAsciiDigit(character))) - { - qualifier.Append(character); - continue; - } - - AppendEscapedCodeUnit(qualifier, character); - } - - if (qualifier.Length == 0) - { - return string.Empty; - } - - return qualifier.ToString(); - - static void AppendEscapedCodeUnit(StringBuilder builder, char codeUnit) - { - builder - .Append("_x") - .Append(((int)codeUnit).ToString("X4", CultureInfo.InvariantCulture)) - .Append('_'); - } + var simpleName = methodName.Contains('.') + ? methodName[(methodName.LastIndexOf('.') + 1)..] + : methodName; + return $"{ToPascalCase(simpleName)}Options"; } /// @@ -1784,9 +1709,7 @@ internal string ResolveOptionsInterfaceName(AtsCapabilityInfo capability) return interfaceName; } - // The fallback has to derive the name the same way registration does, or a capability that - // never reached registration would be emitted referring to an interface nothing declares. - return GetOptionsInterfaceName(capability.MethodName, GetCapabilityOwningAssemblyName(capability)); + return GetOptionsInterfaceName(capability.MethodName); } /// @@ -1842,26 +1765,8 @@ internal static bool TryGetDirectOptionsParameter(List optiona } /// - /// Registers an options interface to be generated later, under a name derived from the assembly - /// that owns and the method that produced it. + /// Registers an options interface to be generated later. /// - /// - /// - /// The name must not depend on which other packages happen to be loaded. The projector runs over - /// whatever an app host references: sdk export scans one integration plus core, while - /// sdk generate scans everything the user's app host pulls in. Naming an interface after - /// its method alone and resolving clashes with a running counter made the result a function of - /// that set, so adding an unrelated integration could rename an interface the user's hand-written - /// TypeScript refers to, and two packages that never meet in one scan could each publish a - /// different RunAsEmulatorOptions — which is TS2717 the moment their API export fragments - /// are concatenated. - /// - /// - /// Qualifying by owning assembly removes both. Every assembly other than the core hosting package - /// gets its own name space, so no two can produce one name, and the name a capability receives is - /// fixed by the capability itself rather than by its company. - /// - /// /// The capability the interface is being registered for. /// The method name the interface is derived from. /// The optional parameters the interface carries. @@ -1877,7 +1782,7 @@ internal void RegisterOptionsInterface( return; } - var baseInterfaceName = GetOptionsInterfaceName(methodName, owningAssemblyName); + var baseInterfaceName = GetOptionsInterfaceName(methodName); // Check if an existing interface with this name is compatible if (_optionsInterfacesToGenerate.TryGetValue(baseInterfaceName, out var existingParams)) @@ -1889,14 +1794,10 @@ internal void RegisterOptionsInterface( return; } - // Incompatible - find or create a suffixed interface. Two capabilities can still collide - // here, but only within one assembly: the qualifier already separates the rest. An - // assembly's own capabilities appear in the same relative order whether the context was - // filtered to that package or holds the whole app host, so the suffix each one draws is - // the same in both, which is what keeps a package export agreeing with full generation. + // Incompatible - find or create a suffixed interface. for (var suffix = 1; ; suffix++) { - var suffixedName = GetOptionsInterfaceName($"{methodName}{suffix}", owningAssemblyName); + var suffixedName = GetOptionsInterfaceName($"{methodName}{suffix}"); if (!_optionsInterfacesToGenerate.TryGetValue(suffixedName, out var suffixedParams)) { // Create a new interface with this suffix diff --git a/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj b/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj index fc558519503..3f7178b5e4d 100644 --- a/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj +++ b/src/Aspire.Hosting.RemoteHost/Aspire.Hosting.RemoteHost.csproj @@ -22,10 +22,6 @@ - - diff --git a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs index c0f533031c5..a187329cca7 100644 --- a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs +++ b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs @@ -70,12 +70,32 @@ public IReadOnlyList GetAssemblies() } } - public bool TryGetRuntimeAssemblyNamesForPackage( + public bool TryGetPackageAssemblyNamesFromProbePaths( string packageId, - [NotNullWhen(true)] - out string? canonicalPackageId, + string packageVersion, out IReadOnlyList assemblyNames) - => _packageProbeManifest.TryGetRuntimeAssemblyNamesForPackage(packageId, out canonicalPackageId, out assemblyNames); + { + ArgumentException.ThrowIfNullOrWhiteSpace(packageId); + ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); + + var names = new SortedSet(StringComparer.OrdinalIgnoreCase); + + foreach (var assembly in _packageProbeManifest.ManagedAssemblies) + { + if (assembly.Culture is not null || + !TryGetPackageIdentityFromAssetPath(assembly.Path, out var pathPackageId, out var pathPackageVersion) || + !string.Equals(pathPackageId, packageId, StringComparison.OrdinalIgnoreCase) || + !string.Equals(pathPackageVersion, packageVersion, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + names.Add(assembly.Name); + } + + assemblyNames = names.ToList(); + return assemblyNames.Count > 0; + } /// /// Snapshots the currently loaded ATS integration assemblies as @@ -134,33 +154,9 @@ internal static IReadOnlyList GetAssemblyNamesToLoad( var assemblyNames = new List(); var seen = new HashSet(StringComparer.OrdinalIgnoreCase); - var configuredAssemblyNames = configuration.GetSection("AtsAssemblies").Get() ?? []; - foreach (var name in configuredAssemblyNames) + foreach (var name in configuration.GetSection("AtsAssemblies").Get() ?? []) { - if (string.IsNullOrWhiteSpace(name)) - { - continue; - } - - // For package-backed polyglot AppHosts, AtsAssemblies can name the NuGet package the - // user requested rather than every assembly inside that package. The probe manifest is - // the only data RemoteHost receives that preserves that package-to-assembly - // relationship, so expand configured package ids before auto-discovering transitive - // Aspire.Hosting assemblies. - if (packageProbeManifest?.TryGetRuntimeAssemblyNamesForPackage(name, out _, out var packageAssemblyNames) == true) - { - foreach (var packageAssemblyName in packageAssemblyNames) - { - if (seen.Add(packageAssemblyName)) - { - assemblyNames.Add(packageAssemblyName); - } - } - - continue; - } - - if (seen.Add(name)) + if (!string.IsNullOrWhiteSpace(name) && seen.Add(name)) { assemblyNames.Add(name); } @@ -177,6 +173,36 @@ internal static IReadOnlyList GetAssemblyNamesToLoad( return assemblyNames; } + private static bool TryGetPackageIdentityFromAssetPath( + string assemblyPath, + [NotNullWhen(true)] out string? packageId, + [NotNullWhen(true)] out string? packageVersion) + { + // NuGet's global-packages layout is: + // ///lib|ref// + // Matching from the assembly upward keeps this export-only lookup independent of the + // configured global-packages root without guessing across unrelated restored packages. + var targetFrameworkDirectory = Directory.GetParent(assemblyPath); + var assetKindDirectory = targetFrameworkDirectory?.Parent; + var versionDirectory = assetKindDirectory?.Parent; + var packageDirectory = versionDirectory?.Parent; + + if (assetKindDirectory is null || + versionDirectory is null || + packageDirectory is null || + (!string.Equals(assetKindDirectory.Name, "lib", StringComparison.OrdinalIgnoreCase) && + !string.Equals(assetKindDirectory.Name, "ref", StringComparison.OrdinalIgnoreCase))) + { + packageId = null; + packageVersion = null; + return false; + } + + packageId = packageDirectory.Name; + packageVersion = versionDirectory.Name; + return true; + } + internal static IReadOnlyList DiscoverAspireHostingAssemblies(IEnumerable directories, IEnumerable? manifestAssemblyNames = null) { var assemblyNames = new SortedSet(StringComparer.OrdinalIgnoreCase); diff --git a/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs b/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs index f19649969e8..9e586055de3 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs @@ -56,11 +56,6 @@ public sealed class ScanResult /// public Dictionary Properties { get; init; } = new(); - /// - /// Runtime registry mapping capability IDs to the assemblies that exported them. - /// - internal Dictionary CapabilityExportingAssemblyNames { get; init; } = new(); - /// /// Converts the scan result to an AtsContext for code generation. /// @@ -73,8 +68,7 @@ public AtsContext ToAtsContext() DtoTypes = DtoTypes, EnumTypes = EnumTypes, ExportedValues = ExportedValues, - Diagnostics = Diagnostics, - CapabilityExportingAssemblyNames = CapabilityExportingAssemblyNames + Diagnostics = Diagnostics }; // Copy runtime registries @@ -86,6 +80,7 @@ public AtsContext ToAtsContext() { context.Properties[id] = property; } + return context; } } @@ -151,7 +146,6 @@ public static ScanResult ScanAssemblies( var allDiagnostics = new List(); var allMethods = new Dictionary(); var allProperties = new Dictionary(); - var allCapabilityExportingAssemblyNames = new Dictionary(); var seenCapabilities = new Dictionary(); // Track capability ID -> first capability for duplicate detection var seenTypeIds = new HashSet(); var seenDtoTypeIds = new HashSet(); @@ -218,10 +212,6 @@ public static ScanResult ScanAssemblies( { allProperties.TryAdd(id, property); } - foreach (var (id, assemblyName) in result.CapabilityExportingAssemblyNames) - { - allCapabilityExportingAssemblyNames.TryAdd(id, assemblyName); - } // Merge diagnostics allDiagnostics.AddRange(result.Diagnostics); @@ -244,8 +234,6 @@ public static ScanResult ScanAssemblies( // Pass 5: Filter method name collisions (overloaded methods) after expansion FilterMethodNameCollisions(allCapabilities, allDiagnostics); - PruneRegistriesToSurvivingCapabilities(allCapabilities, allCapabilityExportingAssemblyNames, allMethods, allProperties); - return new ScanResult { Capabilities = allCapabilities, @@ -255,8 +243,7 @@ public static ScanResult ScanAssemblies( ExportedValues = allExportedValues, Diagnostics = allDiagnostics, Methods = allMethods, - Properties = allProperties, - CapabilityExportingAssemblyNames = allCapabilityExportingAssemblyNames + Properties = allProperties }; } @@ -285,8 +272,6 @@ public static ScanResult ScanAssembly( // Filter method name collisions (overloaded methods) after expansion FilterMethodNameCollisions(result.Capabilities, result.Diagnostics); - PruneRegistriesToSurvivingCapabilities(result.Capabilities, result.CapabilityExportingAssemblyNames, result.Methods, result.Properties); - var exportedValues = DeduplicateExportedValues(result.ExportedValues, result.Diagnostics); return new ScanResult @@ -298,8 +283,7 @@ public static ScanResult ScanAssembly( ExportedValues = exportedValues, Diagnostics = result.Diagnostics, Methods = result.Methods, - Properties = result.Properties, - CapabilityExportingAssemblyNames = result.CapabilityExportingAssemblyNames + Properties = result.Properties }; } @@ -529,10 +513,7 @@ private static ScanResult ScanAssemblyWithoutExpansion( ExportedValues = exportedValues, Diagnostics = diagnostics, Methods = methods, - Properties = properties, - CapabilityExportingAssemblyNames = capabilities - .GroupBy(static capability => capability.CapabilityId, StringComparer.Ordinal) - .ToDictionary(static group => group.Key, _ => assemblyName, StringComparer.Ordinal) + Properties = properties }; } @@ -730,55 +711,6 @@ private static void ResolveTypeRef(AtsTypeRef? typeRef, HashSet validTyp } } - /// - /// Drops the per-capability registry entries for capabilities that scanning removed, so every - /// registry describes exactly the capabilities the scan kept. - /// - /// - /// - /// These registries are populated while assemblies are scanned, before - /// and run. - /// Those filters drop capabilities but cannot reach the registries, so an assembly whose every - /// capability was filtered out would still be named by them. - /// - /// - /// That is not cosmetic. AtsContextFilter.TryResolveCanonicalAssemblyName resolves a - /// requested package against the assembly names these registries carry, so such a package would - /// resolve, filter to nothing, and let sdk export publish an empty API document under a - /// successful exit code. Failing to resolve is what turns that into a reported error. The - /// ownership map alone is not enough: the method and property registries name the same assembly - /// through their declaring types. - /// - /// - /// Removing the entries is safe because every consumer reaches them by the capability id of a - /// capability it already holds, so an entry whose capability is gone is unreachable. - /// - /// - private static void PruneRegistriesToSurvivingCapabilities( - List capabilities, - Dictionary exportingAssemblyNames, - Dictionary methods, - Dictionary properties) - { - // Expansion mutates ExpandedTargetTypes in place and never rewrites CapabilityId, so the - // surviving ids are exactly the keys that should remain. - var survivingCapabilityIds = new HashSet( - capabilities.Select(capability => capability.CapabilityId), - StringComparer.Ordinal); - - RemoveStaleKeys(exportingAssemblyNames, survivingCapabilityIds); - RemoveStaleKeys(methods, survivingCapabilityIds); - RemoveStaleKeys(properties, survivingCapabilityIds); - - static void RemoveStaleKeys(Dictionary registry, HashSet survivingCapabilityIds) - { - foreach (var capabilityId in registry.Keys.Where(id => !survivingCapabilityIds.Contains(id)).ToList()) - { - registry.Remove(capabilityId); - } - } - } - /// /// Filters out capabilities that still have Unknown types after resolution. /// These are capabilities that use types not in the ATS universe. diff --git a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs index a126ee9aa77..f1fc4722c68 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs @@ -44,30 +44,13 @@ public static bool TryResolveCanonicalAssemblyName( ArgumentNullException.ThrowIfNull(context); ArgumentException.ThrowIfNullOrWhiteSpace(requestedName); - // Seed with the exporting assembly names rather than gathering them afterwards. They are the - // first thing IsCapabilityOwnedBySelectedAssembly consults, so when a capability's recorded - // exporter disagrees with its declaring assembly, the exporter is the spelling that decides - // ownership and must be the one that wins here too. Everything else comes from - // GetKnownAssemblyNames so this cannot drift from the names the filter recognizes -- notably - // the ones parsed out of capability and type ids, which are the only trace of an assembly - // whose CLR types did not resolve. - var candidates = GetKnownAssemblyNames(context, GetExportingAssemblyNames(context)); + var candidates = GetKnownAssemblyNames( + context, + new HashSet(StringComparer.OrdinalIgnoreCase)); return candidates.TryGetValue(requestedName, out canonicalName); } - private static HashSet GetExportingAssemblyNames(AtsContext context) - { - var exportingAssemblyNames = new HashSet(StringComparer.OrdinalIgnoreCase); - - foreach (var assemblyName in context.CapabilityExportingAssemblyNames.Values) - { - AddAssemblyName(exportingAssemblyNames, assemblyName); - } - - return exportingAssemblyNames; - } - /// /// Filters the given ATS context to include only capabilities and types exported by the specified assemblies. /// @@ -156,13 +139,7 @@ internal static AtsContext FilterForApiExport( DtoTypes = filteredContext.DtoTypes, EnumTypes = filteredContext.EnumTypes, ExportedValues = filteredContext.ExportedValues, - Diagnostics = filteredContext.Diagnostics, - CapabilityExportingAssemblyNames = capabilities - .Where(capability => context.CapabilityExportingAssemblyNames.ContainsKey(capability.CapabilityId)) - .ToDictionary( - capability => capability.CapabilityId, - capability => context.CapabilityExportingAssemblyNames[capability.CapabilityId], - StringComparer.Ordinal) + Diagnostics = filteredContext.Diagnostics }; foreach (var capability in capabilities) @@ -308,13 +285,7 @@ private static AtsContext FilterByExportingAssemblies( ExportedValues = filteredExportedValues, Diagnostics = context.Diagnostics .Where(diagnostic => IsDiagnosticOwnedBySelectedAssembly(context, diagnostic, normalizedAssemblyNames, knownAssemblyNames)) - .ToList(), - CapabilityExportingAssemblyNames = filteredCapabilities - .Where(capability => context.CapabilityExportingAssemblyNames.ContainsKey(capability.CapabilityId)) - .ToDictionary( - capability => capability.CapabilityId, - capability => context.CapabilityExportingAssemblyNames[capability.CapabilityId], - StringComparer.Ordinal) + .ToList() }; foreach (var capability in filteredCapabilities) @@ -531,11 +502,6 @@ private static bool IsCapabilityOwnedBySelectedAssembly( AtsCapabilityInfo capability, HashSet assemblyNames) { - if (context.CapabilityExportingAssemblyNames.TryGetValue(capability.CapabilityId, out var exportingAssemblyName)) - { - return assemblyNames.Contains(exportingAssemblyName); - } - if (context.Methods.TryGetValue(capability.CapabilityId, out var method)) { return IsSelectedAssembly(method.DeclaringType?.Assembly, assemblyNames); diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index a225aea9eab..39f00a86c2c 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -6,6 +6,7 @@ using Aspire.Hosting.RemoteHost.Diagnostics; using Microsoft.Extensions.Logging; using StreamJsonRpc; +using StreamJsonRpc.Protocol; namespace Aspire.Hosting.RemoteHost.CodeGeneration; @@ -282,17 +283,31 @@ public Dictionary GenerateCode(string language, string? assembly /// The version label to record for . The caller owns its accuracy; /// see . /// + /// A token to cancel the export. /// The language provider's API reference document, verbatim. [JsonRpcMethod(ExportApiMethodName)] - public JsonElement ExportApi(string language, string packageName, string packageVersion) + public JsonElement ExportApi( + string language, + string packageName, + string packageVersion, + CancellationToken cancellationToken) { using var rpcActivity = _profilingTelemetry.StartJsonRpcServerCall(ExportApiMethodName); - using var activity = _profilingTelemetry.StartCodeGenerationExportApi(language); try { _authenticationState.ThrowIfNotAuthenticated(); - ArgumentException.ThrowIfNullOrWhiteSpace(packageName); - ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); + if (string.IsNullOrWhiteSpace(language)) + { + throw CreateInvalidExportRequest("The export language cannot be empty."); + } + if (string.IsNullOrWhiteSpace(packageName)) + { + throw CreateInvalidExportRequest("The export package name cannot be empty."); + } + if (string.IsNullOrWhiteSpace(packageVersion)) + { + throw CreateInvalidExportRequest("The export package version cannot be empty."); + } _logger.LogDebug(">> exportApi({Language}, {PackageName}, {PackageVersion})", language, packageName, packageVersion); var sw = System.Diagnostics.Stopwatch.StartNew(); @@ -300,7 +315,7 @@ public JsonElement ExportApi(string language, string packageName, string package var generator = _resolver.GetCodeGenerator(language); if (generator is null) { - throw new ArgumentException(BuildNoCodeGeneratorMessage(language)); + throw CreateInvalidExportRequest(BuildNoCodeGeneratorMessage(language)); } // Resolved through the resolver rather than cast off the generator: the exporter is @@ -308,7 +323,7 @@ public JsonElement ExportApi(string language, string packageName, string package // type's eagerly resolved interface list. See AtsTypeScriptApiReferenceExporter. if (_resolver.GetApiReferenceExporter(language) is not { } exporter) { - throw new NotSupportedException( + throw CreateInvalidExportRequest( $"The '{generator.Language}' language provides no {nameof(IApiReferenceExporter)}, " + "so it cannot produce an API reference export. " + $"Supported languages for API export: {BuildApiExportLanguageList()}."); @@ -319,13 +334,20 @@ public JsonElement ExportApi(string language, string packageName, string package // package. var fullContext = _atsContextFactory.GetContext(); - var exportingAssemblyNames = ResolvePackageExportingAssemblyNames(fullContext, packageName, out var canonicalPackageName); + var exportingAssemblyNames = ResolvePackageExportingAssemblyNames( + fullContext, + packageName, + packageVersion, + out var canonicalPackageName); var context = AtsContextFilter.FilterForApiExport( fullContext, exportingAssemblyNames); - var export = exporter.ExportApi(context, new ApiReferenceExportOptions(canonicalPackageName, packageVersion, exportingAssemblyNames)); + var export = exporter.ExportApi( + context, + new ApiReferenceExportOptions(canonicalPackageName, packageVersion, exportingAssemblyNames), + cancellationToken); _logger.LogDebug("<< exportApi({Language}, {PackageName}) completed in {ElapsedMs}ms", language, packageName, sw.ElapsedMilliseconds); @@ -335,7 +357,6 @@ public JsonElement ExportApi(string language, string packageName, string package } catch (Exception ex) { - activity.SetError(ex); _logger.LogError(ex, "<< exportApi({Language}, {PackageName}) failed", language, packageName); var wrapped = CodeGenerationDiagnosticBuilder.TryCreateRpcException(ex, _assemblyLoader, _logger); if (wrapped is not null) @@ -346,12 +367,22 @@ public JsonElement ExportApi(string language, string packageName, string package } } + private static LocalRpcException CreateInvalidExportRequest(string message) + => new(message) + { + ErrorCode = (int)JsonRpcErrorCode.InvalidParams + }; + private IReadOnlyList ResolvePackageExportingAssemblyNames( AtsContext fullContext, string packageName, + string packageVersion, out string canonicalPackageName) { - if (_assemblyLoader.TryGetRuntimeAssemblyNamesForPackage(packageName, out var manifestPackageName, out var manifestAssemblyNames)) + if (_assemblyLoader.TryGetPackageAssemblyNamesFromProbePaths( + packageName, + packageVersion, + out var manifestAssemblyNames)) { var exportingAssemblyNames = new List(manifestAssemblyNames.Count); foreach (var assemblyName in manifestAssemblyNames) @@ -365,10 +396,11 @@ private IReadOnlyList ResolvePackageExportingAssemblyNames( if (exportingAssemblyNames.Count == 0) { throw new InvalidOperationException( - $"'{packageName}' restored, but none of its runtime assemblies reached the scanned API surface, so there is no API to export under it."); + $"Package '{packageName}' version '{packageVersion}' was mapped from restored asset paths, " + + "but none of its assemblies reached the scanned API surface."); } - canonicalPackageName = manifestPackageName; + canonicalPackageName = packageName; return exportingAssemblyNames; } @@ -381,9 +413,8 @@ private IReadOnlyList ResolvePackageExportingAssemblyNames( if (!AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, packageName, out var canonicalAssemblyNameFromContext)) { throw new InvalidOperationException( - $"'{packageName}' restored, but the scanned API surface contains nothing under that name, so there is no API to export under it. " + - "An API export is scoped by assembly name, so this is what a package whose assembly is named something other than " + - "its package id looks like from here."); + $"No managed assemblies for package '{packageName}' version '{packageVersion}' could be mapped from the restored asset paths, " + + "and the scanned API surface contains no assembly with the package id as its name."); } canonicalPackageName = canonicalAssemblyNameFromContext; diff --git a/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs b/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs index d07a310ff36..6722dbafade 100644 --- a/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs +++ b/src/Aspire.Hosting.RemoteHost/Diagnostics/RemoteHostProfilingTelemetry.cs @@ -46,7 +46,6 @@ internal static class Activities public const string CapabilityInvoke = "aspire.hosting.remotehost.capability.invoke"; public const string CodeGenerationGetCapabilities = "aspire.hosting.remotehost.codegen.get_capabilities"; public const string CodeGenerationGenerate = "aspire.hosting.remotehost.codegen.generate"; - public const string CodeGenerationExportApi = "aspire.hosting.remotehost.codegen.export_api"; public const string LanguageDetect = "aspire.hosting.remotehost.language.detect"; public const string LanguageGetRuntimeSpec = "aspire.hosting.remotehost.language.get_runtime_spec"; public const string LanguageScaffold = "aspire.hosting.remotehost.language.scaffold"; @@ -195,13 +194,6 @@ public ActivityScope StartCodeGenerationGenerate(string language) return activity; } - public ActivityScope StartCodeGenerationExportApi(string language) - { - var activity = StartActivity(Activities.CodeGenerationExportApi, ActivityKind.Server); - activity.SetLanguage(language); - return activity; - } - public ActivityScope StartLanguageDetect() { return StartActivity(Activities.LanguageDetect, ActivityKind.Server); diff --git a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs index b30c1f4916f..a027af5a608 100644 --- a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs +++ b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs @@ -138,9 +138,7 @@ internal static IntegrationPackageProbeManifest CreateManifest(IEnumerable Assets, int SkippedCount) Resol // Synthetic restores can leave the base lib assembly in the target even when the package // contains a compatible portable runtime asset. Prefer the runtime asset for probing. var runtimeAssemblyOverrides = GetRuntimeAssemblyOverrides(packageLibrary, targetFramework, runtimeIdentifiers); - AddRuntimeAssemblies(assets, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides, libraryName, libraryVersion); - AddRuntimeTargets(assets, library.RuntimeTargets, packagePath, libraryName, libraryVersion); - AddResourceAssemblies(assets, library.ResourceAssemblies, packagePath, libraryName, libraryVersion); - AddNativeLibraries(assets, library.NativeLibraries, packagePath, libraryName, libraryVersion); + AddRuntimeAssemblies(assets, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides); + AddRuntimeTargets(assets, library.RuntimeTargets, packagePath); + AddResourceAssemblies(assets, library.ResourceAssemblies, packagePath); + AddNativeLibraries(assets, library.NativeLibraries, packagePath); return (assets, 0); } @@ -167,9 +163,7 @@ private static void AddRuntimeAssemblies( List assets, IEnumerable runtimeAssemblies, string packagePath, - IReadOnlyDictionary runtimeAssemblyOverrides, - string packageId, - string packageVersion) + IReadOnlyDictionary runtimeAssemblyOverrides) { foreach (var runtimeAssembly in runtimeAssemblies) { @@ -182,20 +176,18 @@ private static void AddRuntimeAssemblies( if (!relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase) && runtimeAssemblyOverrides.TryGetValue(GetFileName(relativePath), out var overridePath)) { - AddRuntimeAssembly(assets, packagePath, overridePath, packageId, packageVersion); + AddRuntimeAssembly(assets, packagePath, overridePath); continue; } - AddRuntimeAssembly(assets, packagePath, relativePath, packageId, packageVersion); + AddRuntimeAssembly(assets, packagePath, relativePath); } } private static void AddRuntimeAssembly( List assets, string packagePath, - string relativePath, - string packageId, - string packageVersion) + string relativePath) { var sourcePath = Path.Combine(packagePath, relativePath.Replace('/', Path.DirectorySeparatorChar)); if (!File.Exists(sourcePath)) @@ -204,38 +196,17 @@ private static void AddRuntimeAssembly( } var fileName = Path.GetFileName(sourcePath); - AddAsset( - assets, - sourcePath, - fileName, - isManagedAssembly: IsManagedAssembly(sourcePath), - isNativeLibrary: false, - packageId: packageId, - packageVersion: packageVersion); + AddAsset(assets, sourcePath, fileName, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); if (relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase)) { - AddAsset( - assets, - sourcePath, - relativePath, - isManagedAssembly: IsManagedAssembly(sourcePath), - isNativeLibrary: false, - packageId: packageId, - packageVersion: packageVersion); + AddAsset(assets, sourcePath, relativePath, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); } var xmlSourcePath = Path.ChangeExtension(sourcePath, ".xml"); if (File.Exists(xmlSourcePath)) { - AddAsset( - assets, - xmlSourcePath, - Path.ChangeExtension(fileName, ".xml"), - isManagedAssembly: false, - isNativeLibrary: false, - packageId: packageId, - packageVersion: packageVersion); + AddAsset(assets, xmlSourcePath, Path.ChangeExtension(fileName, ".xml"), isManagedAssembly: false, isNativeLibrary: false); } } @@ -339,9 +310,7 @@ private static string GetFileName(string path) private static void AddRuntimeTargets( List assets, IEnumerable runtimeTargets, - string packagePath, - string packageId, - string packageVersion) + string packagePath) { foreach (var runtimeTarget in runtimeTargets) { @@ -361,18 +330,14 @@ private static void AddRuntimeTargets( sourcePath, runtimeTarget.Path, isManagedAssembly: string.Equals(runtimeTarget.AssetType, "runtime", StringComparison.OrdinalIgnoreCase) && IsManagedAssembly(sourcePath), - isNativeLibrary: string.Equals(runtimeTarget.AssetType, "native", StringComparison.OrdinalIgnoreCase), - packageId: packageId, - packageVersion: packageVersion); + isNativeLibrary: string.Equals(runtimeTarget.AssetType, "native", StringComparison.OrdinalIgnoreCase)); } } private static void AddResourceAssemblies( List assets, IEnumerable resourceAssemblies, - string packagePath, - string packageId, - string packageVersion) + string packagePath) { foreach (var resourceAssembly in resourceAssemblies) { @@ -402,8 +367,6 @@ private static void AddResourceAssemblies( Path.Combine(locale, Path.GetFileName(sourcePath)), isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false, - packageId: packageId, - packageVersion: packageVersion, culture: locale); } } @@ -411,9 +374,7 @@ private static void AddResourceAssemblies( private static void AddNativeLibraries( List assets, IEnumerable nativeLibraries, - string packagePath, - string packageId, - string packageVersion) + string packagePath) { foreach (var nativeLib in nativeLibraries) { @@ -428,22 +389,8 @@ private static void AddNativeLibraries( continue; } - AddAsset( - assets, - sourcePath, - Path.GetFileName(sourcePath), - isManagedAssembly: false, - isNativeLibrary: true, - packageId: packageId, - packageVersion: packageVersion); - AddAsset( - assets, - sourcePath, - nativeLib.Path, - isManagedAssembly: false, - isNativeLibrary: true, - packageId: packageId, - packageVersion: packageVersion); + AddAsset(assets, sourcePath, Path.GetFileName(sourcePath), isManagedAssembly: false, isNativeLibrary: true); + AddAsset(assets, sourcePath, nativeLib.Path, isManagedAssembly: false, isNativeLibrary: true); } } @@ -453,8 +400,6 @@ private static void AddAsset( string relativePath, bool isManagedAssembly, bool isNativeLibrary, - string packageId, - string packageVersion, string? culture = null) { assets.Add(new NuGetPackageAsset @@ -463,9 +408,7 @@ private static void AddAsset( RelativePath = NormalizeRelativePath(relativePath), IsManagedAssembly = isManagedAssembly, IsNativeLibrary = isNativeLibrary, - Culture = culture, - PackageId = packageId, - PackageVersion = packageVersion + Culture = culture }); } diff --git a/src/Aspire.TypeSystem/AtsContext.cs b/src/Aspire.TypeSystem/AtsContext.cs index 6fd06279613..29722166100 100644 --- a/src/Aspire.TypeSystem/AtsContext.cs +++ b/src/Aspire.TypeSystem/AtsContext.cs @@ -98,17 +98,6 @@ public sealed class AtsContext /// public Dictionary Properties { get; } = new(); - /// - /// Gets the assemblies that exported each capability, keyed by capability ID. - /// - /// - /// The declaring CLR type can belong to another assembly when an assembly-level - /// AspireExport exposes an external type, so reflection alone cannot determine - /// which package owns the exported capability. - /// - public IReadOnlyDictionary CapabilityExportingAssemblyNames { get; init; } = - new Dictionary(); - /// /// Gets the type category for a CLR type based on scanned data. /// Used at runtime for marshalling. diff --git a/src/Aspire.TypeSystem/IApiReferenceExporter.cs b/src/Aspire.TypeSystem/IApiReferenceExporter.cs index 0dc026fbf7c..ca88166281f 100644 --- a/src/Aspire.TypeSystem/IApiReferenceExporter.cs +++ b/src/Aspire.TypeSystem/IApiReferenceExporter.cs @@ -36,6 +36,10 @@ public interface IApiReferenceExporter /// /// The ATS context containing capabilities, types, and enums. /// The package identity and ownership scope for the export. + /// A token to cancel the export between projected items. /// A language-defined JSON document describing the generated API. - JsonElement ExportApi(AtsContext context, ApiReferenceExportOptions options); + JsonElement ExportApi( + AtsContext context, + ApiReferenceExportOptions options, + CancellationToken cancellationToken); } diff --git a/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs b/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs deleted file mode 100644 index b876aee32b6..00000000000 --- a/src/Shared/CodeGeneration/TypeScriptOptionsInterfaceNaming.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Aspire.Shared.CodeGeneration; - -internal static class TypeScriptOptionsInterfaceNaming -{ - private const string AspireHostingAssembly = "Aspire.Hosting"; - private const string AspireHostingAssemblyPrefix = "Aspire.Hosting."; - - // These are the duplicate unqualified names in the checked-in shipped ATS surface. First-party - // packages keep unique names unqualified for compatibility; when the TypeScript API - // compatibility guard finds a new duplicate, add that name here so non-core Aspire packages - // move to package-qualified names together. Third-party packages are always qualified because - // the repository guard cannot see their collisions before users concatenate package exports. - internal static IReadOnlySet PackageQualifiedOptionsInterfaceNames { get; } = - new HashSet(StringComparer.Ordinal) - { - "AddCertManagerOptions", - "AddDatabaseOptions", - "AddHubOptions", - "AddSecretOptions", - "RunAsContainerOptions", - "RunAsEmulatorOptions", - "WithAccessKeyAuthenticationOptions", - "WithDashboardOptions", - "WithDataBindMountOptions", - "WithDataVolumeOptions", - "WithForwardedHeadersOptions", - "WithHostPortOptions", - "WithHttpsUpgradeOptions", - "WithOtlpExporterOptions", - "WithPersistenceOptions", - "WithPostgresMcpOptions" - }; - - internal static bool RequiresPackageQualifier(string unqualifiedInterfaceName) - => PackageQualifiedOptionsInterfaceNames.Contains(unqualifiedInterfaceName); - - internal static bool RequiresPackageQualifier(string unqualifiedInterfaceName, string owningAssemblyName) - { - if (string.IsNullOrEmpty(owningAssemblyName) || - string.Equals(owningAssemblyName, AspireHostingAssembly, StringComparison.Ordinal)) - { - return false; - } - - if (!owningAssemblyName.StartsWith(AspireHostingAssemblyPrefix, StringComparison.Ordinal)) - { - return true; - } - - return RequiresPackageQualifier(unqualifiedInterfaceName); - } - - internal static string GetUnqualifiedOptionsInterfaceName(string methodName) - { - var simpleName = methodName.Contains('.') - ? methodName[(methodName.LastIndexOf('.') + 1)..] - : methodName; - - return $"{ToPascalCase(simpleName)}Options"; - } - - private static string ToPascalCase(string name) - { - if (string.IsNullOrEmpty(name)) - { - return name; - } - - if (char.IsUpper(name[0])) - { - return name; - } - - return char.ToUpperInvariant(name[0]) + name[1..]; - } -} diff --git a/src/Shared/IntegrationPackageProbeManifest.cs b/src/Shared/IntegrationPackageProbeManifest.cs index e3a57ea8416..24b8fa64743 100644 --- a/src/Shared/IntegrationPackageProbeManifest.cs +++ b/src/Shared/IntegrationPackageProbeManifest.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; using System.Text.Json; @@ -51,9 +50,7 @@ public static IntegrationPackageProbeManifest Create( { Name = NormalizeRequiredValue(assembly.Name, "managedAssemblies[].name"), Culture = NormalizeCulture(assembly.Culture), - Path = NormalizeRequiredValue(assembly.Path, "managedAssemblies[].path"), - PackageId = NormalizeOptionalValue(assembly.PackageId), - PackageVersion = NormalizeOptionalValue(assembly.PackageVersion) + Path = NormalizeRequiredValue(assembly.Path, "managedAssemblies[].path") }; managedLookup.TryAdd( @@ -145,14 +142,6 @@ public static Task WriteAsync( { writer.WriteString("culture", managedAssembly.Culture); } - if (managedAssembly.PackageId is not null) - { - writer.WriteString("packageId", managedAssembly.PackageId); - } - if (managedAssembly.PackageVersion is not null) - { - writer.WriteString("packageVersion", managedAssembly.PackageVersion); - } writer.WriteString("path", managedAssembly.Path); writer.WriteEndObject(); } @@ -188,32 +177,6 @@ public static Task WriteAsync( : null; } - public bool TryGetRuntimeAssemblyNamesForPackage( - string packageId, - [NotNullWhen(true)] out string? canonicalPackageId, - out IReadOnlyList assemblyNames) - { - ArgumentException.ThrowIfNullOrWhiteSpace(packageId); - - var names = new SortedSet(StringComparer.OrdinalIgnoreCase); - canonicalPackageId = null; - - foreach (var assembly in ManagedAssemblies) - { - if (assembly.Culture is not null || - !string.Equals(assembly.PackageId, packageId, StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - canonicalPackageId ??= assembly.PackageId; - names.Add(assembly.Name); - } - - assemblyNames = names.ToList(); - return assemblyNames.Count > 0; - } - public IReadOnlyList GetNativeLibraryPaths(string unmanagedDllName) { var candidatePaths = new List(); @@ -407,11 +370,6 @@ private static string NormalizeRequiredValue(string? value, string propertyName) return value.Trim(); } - private static string? NormalizeOptionalValue(string? value) - { - return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); - } - private static IReadOnlyList ReadManagedAssemblies(JsonElement rootElement) { if (!rootElement.TryGetProperty("managedAssemblies", out var managedAssembliesElement) || @@ -427,9 +385,7 @@ private static IReadOnlyList ReadManagedAssem { Name = NormalizeRequiredValue(ReadStringProperty(element, "name"), "managedAssemblies[].name"), Culture = NormalizeCulture(ReadStringProperty(element, "culture", required: false)), - Path = NormalizeAndValidatePath(ReadStringProperty(element, "path"), "managedAssemblies[].path"), - PackageId = NormalizeOptionalValue(ReadStringProperty(element, "packageId", required: false)), - PackageVersion = NormalizeOptionalValue(ReadStringProperty(element, "packageVersion", required: false)) + Path = NormalizeAndValidatePath(ReadStringProperty(element, "path"), "managedAssemblies[].path") }); } @@ -489,10 +445,6 @@ internal sealed class IntegrationPackageManagedAssembly public string? Culture { get; init; } public required string Path { get; init; } - - public string? PackageId { get; init; } - - public string? PackageVersion { get; init; } } /// diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 4f0f2000ebd..55882cad276 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -8,20 +8,13 @@ using Aspire.Cli.Projects; using Aspire.Cli.Tests.TestServices; using Aspire.Cli.Tests.Utils; -using Aspire.Cli.Commands.Sdk; using Microsoft.AspNetCore.InternalTesting; using Microsoft.Extensions.DependencyInjection; -using Semver; using StreamJsonRpc; +using StreamJsonRpc.Protocol; namespace Aspire.Cli.Tests.Commands.Sdk; -/// -/// Covers aspire sdk export. The command exists to feed documentation pipelines, so the -/// discipline it needs is unusual for a CLI command: stdout has to be exactly one machine-readable -/// document with nothing else mixed in, and the package version has to be exact so published -/// documentation can be keyed on it. -/// public class SdkExportCommandTests(ITestOutputHelper outputHelper) { [Fact] @@ -31,811 +24,197 @@ public async Task SdkExportWithHelpReturnsZero() var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper); using var provider = services.BuildServiceProvider(); - var command = provider.GetRequiredService(); - var result = command.Parse("sdk export --help"); - - var exitCode = await result.InvokeAsync().DefaultTimeout(); + var exitCode = await InvokeAsync(provider, "sdk export --help"); - Assert.Equal(0, exitCode); + Assert.Equal(CliExitCodes.Success, exitCode); } - /// - /// The server keys generators by ICodeGenerator.Language, so every accepted spelling of a - /// language has to arrive there as the generator name. The canonical language id is the spelling - /// most likely to be typed and the one furthest from the generator name. - /// [Theory] [InlineData("typescript/nodejs")] [InlineData("typescript")] [InlineData("TypeScript")] - public async Task SdkExportSendsTheGeneratorNameForEveryAcceptedLanguageSpelling(string language) + public async Task SdkExportSendsTheResolvedGeneratorName(string language) { var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); - using var _ = workspace; + using var provider = CreateProvider( + interactionService, + out var workspace, + out var rpcClient, + out _); + using var workspaceLease = workspace; var exitCode = await InvokeAsync(provider, $"sdk export --language {language}"); Assert.Equal(CliExitCodes.Success, exitCode); - var request = Assert.NotNull(rpcClient.LastExportRequest); - Assert.Equal("TypeScript", request.Language); - } - - [Fact] - public async Task SdkExportForExactPackageWritesCanonicalDocumentToStdout() - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); - using var _ = workspace; - var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion}"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "Aspire.Hosting.Redis", packageVersion), rpcClient.LastExportRequest); - - var stdout = Assert.Single(interactionService.DisplayedRawText, entry => entry.ConsoleOverride == ConsoleOutput.Standard); - using var document = JsonDocument.Parse(stdout.Text); - Assert.Equal(1, document.RootElement.GetProperty("schemaVersion").GetInt32()); - Assert.Equal("Aspire.Hosting.Redis", document.RootElement.GetProperty("package").GetProperty("name").GetString()); - } - - [Fact] - public async Task SdkExportDefaultsToCoreHostingAtTheRunningSdkVersion() - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); - using var _ = workspace; - - var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); - - Assert.Equal(CliExitCodes.Success, exitCode); - - // Defaulting to the CLI's own SDK version is the entire point of the command: documentation - // must describe the SDK this CLI would actually generate against, not a floating latest. - var expectedVersion = provider.GetRequiredService().IdentitySdkVersion; - Assert.Equal(("TypeScript", "Aspire.Hosting", expectedVersion), rpcClient.LastExportRequest); + Assert.Equal("TypeScript", Assert.NotNull(rpcClient.LastExportRequest).Language); } [Fact] - public async Task SdkExportDefaultsToTheIdentityVersionWithoutItsBuildMetadata() + public async Task SdkExportRestoresExactPackageAndWritesOnlyJsonToStdout() { var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var rpcClient = new StubExportRpcClient(); using var provider = CreateProvider( interactionService, - workspace, - rpcClient, - new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName), - identityVersion: "13.5.0-dev+abc123"); - - var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); - - Assert.Equal(CliExitCodes.Success, exitCode); - - // A real informational version carries the commit suffix. NuGet ignores it for identity, so - // exporting under it would label the document with a version no feed serves. - Assert.Equal(("TypeScript", "Aspire.Hosting", "13.5.0-dev"), rpcClient.LastExportRequest); - } - - [Fact] - public async Task SdkExportPublishesTheNormalizedVersionForAnAbbreviatedRequest() - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out var rpcClient); - using var _ = workspace; + out var workspace, + out var rpcClient, + out var project); + using var workspaceLease = workspace; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0"); + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0"); Assert.Equal(CliExitCodes.Success, exitCode); - - // NuGet resolves Contoso.Aspire.Widgets@2.0 to the 2.0.0 package, so the document has to be - // keyed on the version that was actually restored. Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); - } - - [Fact] - public async Task SdkExportSendsProgressToStderrOnly() - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out _); - using var _2 = workspace; - var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion} --output " + Path.Combine(workspace.WorkspaceRoot.FullName, "api.json")); + var package = Assert.Single( + project.Integrations, + integration => integration.Name == "Contoso.Aspire.Widgets"); + Assert.Equal("[2.0.0]", package.Version); - Assert.Equal(CliExitCodes.Success, exitCode); + var generator = Assert.Single( + project.Integrations, + integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); + var cliVersion = provider.GetRequiredService().IdentityVersion; + Assert.Equal(cliVersion, generator.Version); - // A null per-call override means the message follows the service's Console, so asserting on - // the override alone passes vacuously. Resolve the effective destination instead. Assert.Equal(ConsoleOutput.Error, interactionService.Console); + var stdout = Assert.Single( + interactionService.DisplayedRawText, + entry => entry.ConsoleOverride == ConsoleOutput.Standard); + Assert.DoesNotContain('\r', stdout.Text); + + using var document = JsonDocument.Parse(stdout.Text); + Assert.Equal("Contoso.Aspire.Widgets", document.RootElement.GetProperty("package").GetProperty("name").GetString()); Assert.DoesNotContain( interactionService.DisplayedMessages, message => (message.ConsoleOverride ?? interactionService.Console) == ConsoleOutput.Standard); - - // DisplaySuccess cannot be overridden per call, so the --output confirmation would land on - // stdout and corrupt a piped document if the service were not routed to stderr. - Assert.NotEmpty(interactionService.DisplayedSuccess); - } - - [Fact] - public async Task SdkExportPassesPackageSourceThroughToPrepare() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); - using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); - var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion} --source /tmp/aspire-hive"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal("/tmp/aspire-hive", appHostServerProject.PackageSourceOverride); } - /// - /// The code generator ships in its own package that the scanner AppHost does not reference by - /// default. Without adding it the server loads no generators and every export fails with - /// "No code generator found", which is exactly how this regressed once already. - /// [Fact] - public async Task SdkExportAddsTheCodeGenerationPackageForTheRequestedLanguage() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); - using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); - var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion}"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Contains( - appHostServerProject.Integrations, - integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); - } - - [Theory] - [InlineData("\"\"")] - [InlineData("\" \"")] - public async Task SdkExportDoesNotResolveABlankLanguageToTheFirstDiscoveredOne(string language) + public async Task SdkExportDefaultsToCoreAtTheRunningSdkVersion() { var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); + using var provider = CreateProvider( + interactionService, + out var workspace, + out var rpcClient, + out var project); + using var workspaceLease = workspace; - var exitCode = await InvokeAsync(provider, $"sdk export --language {language}"); + var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); - // Every language id starts with the empty string, so the prefix match resolved `--language ""` - // to whichever language was discovered first and then tried to restore a generator package for - // it, which threw ArgumentException and surfaced as "An unexpected error occurred". A blank - // value has to stay unresolved and travel verbatim so the server produces the authoritative - // unsupported-language error instead. Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Empty(interactionService.DisplayedErrors); - Assert.DoesNotContain( - appHostServerProject.Integrations, - integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); - Assert.Equal("", rpcClient.LastExportRequest?.Language?.Trim()); + var expectedVersion = provider.GetRequiredService().IdentitySdkVersion; + Assert.Equal(("TypeScript", "Aspire.Hosting", expectedVersion), rpcClient.LastExportRequest); + Assert.DoesNotContain(project.Integrations, integration => integration.Name == "Aspire.Hosting"); } [Theory] [InlineData("Aspire.Hosting")] [InlineData("Aspire.Hosting@")] [InlineData("@13.5.0")] - [InlineData("Aspire.Hosting@not-a-version")] + [InlineData(" @13.5.0")] [InlineData("Aspire@Hosting@13.5.0")] - public async Task SdkExportWithMalformedPackageReturnsInvalidCommand(string package) - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out _); - using var _2 = workspace; - - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package \"{package}\""); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Empty(interactionService.DisplayedRawText); - } - - [Fact] - public async Task SdkExportWithMismatchedCoreVersionReturnsInvalidCommand() - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out _); - using var _2 = workspace; - - // The scanner loads the core assemblies this CLI ships with, so honouring a different core - // version would export this CLI's surface under someone else's version number — the same - // stale-signature problem this command exists to fix. - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@1.0.0"); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Empty(interactionService.DisplayedRawText); - } - - [Fact] - public async Task SdkExportAcceptsCoreVersionThatDiffersOnlyByBuildMetadata() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName)); - - var executionContext = provider.GetRequiredService(); - - var exitCode = await InvokeAsync( - provider, - $"sdk export --language typescript --package Aspire.Hosting@{executionContext.IdentitySdkVersion}+build.5"); - - Assert.Equal(0, exitCode); - - // The metadata is accepted but must not survive into the document: see - // SdkExportPublishesTheVersionNuGetResolvesRatherThanTheRequestedBuildMetadata. - Assert.Equal( - ("TypeScript", "Aspire.Hosting", executionContext.IdentitySdkVersion), - rpcClient.LastExportRequest); - } - - /// - /// SemVer build metadata is not part of NuGet package identity, so 2.0.0+fake restores the - /// same package 2.0.0 does. Publishing the surface under the requested string would label - /// the document with a version no feed can serve, which is exactly the exact-version guarantee - /// this command exists to make. The restore pin has to agree for the same reason. - /// - [Fact] - public async Task SdkExportPublishesTheVersionNuGetResolvesRatherThanTheRequestedBuildMetadata() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); - - var exitCode = await InvokeAsync( - provider, - "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0+fake"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); - - var requested = Assert.Single( - appHostServerProject.Integrations, - integration => integration.Name == "Contoso.Aspire.Widgets"); - Assert.Equal("2.0.0", requested.Version); - } - - /// - /// The four-segment path normalizes separately from the semver one, so it gets the same - /// build-metadata guarantee: NuGet ignores metadata for identity, and the document must be - /// labelled with the version a feed can actually serve. - /// - [Fact] - public async Task SdkExportPublishesAFourSegmentVersionWithoutItsBuildMetadata() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); - - var exitCode = await InvokeAsync( - provider, - "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0.4+fake"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0.4"), rpcClient.LastExportRequest); - - var requested = Assert.Single( - appHostServerProject.Integrations, - integration => integration.Name == "Contoso.Aspire.Widgets"); - Assert.Equal("2.0.0.4", requested.Version); - } - - [Theory] - [InlineData("13.5.*")] - [InlineData("[13.5.0,14.0.0)")] - [InlineData("13.5.0-*")] - public async Task SdkExportWithFloatingVersionReturnsInvalidCommand(string version) - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out _); - using var _2 = workspace; - - // Floating versions are rejected before restore rather than resolved, because a document - // published under a range would silently describe a different SDK on the next restore. - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package \"Aspire.Hosting@{version}\""); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Empty(interactionService.DisplayedRawText); - } - - [Fact] - public async Task SdkExportForAPackageTheCheckoutWouldSubstituteReturnsInvalidCommand() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.5.0"); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", "13.5.0"); - - // A CLI running from a repository checkout builds first-party integrations from src/ and - // throws the requested package version away, so honouring this would publish the 13.5.0 - // checkout's API surface under 13.4.0 — the mislabel this command exists to prevent. Both - // halves are pinned rather than derived from the running assembly so the rejection turns on - // the checkout-versus-request mismatch and not on whether this build carries a prerelease - // label, which an official release build strips. - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.4.0"); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Null(rpcClient.LastExportRequest); - Assert.Empty(interactionService.DisplayedRawText); - } - - [Fact] - public async Task SdkExportForASubstitutedPackageAtTheCheckoutVersionSucceeds() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", CheckoutVersionPrefix(provider)); - - // Exporting the version the checkout actually contains is the local development case and - // stays supported: the project reference and the label describe the same surface. - var checkoutVersion = provider.GetRequiredService().IdentitySdkVersion; - - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{checkoutVersion}"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "Aspire.Hosting.Redis", checkoutVersion), rpcClient.LastExportRequest); - } - - [Fact] - public async Task SdkExportRejectsWhenTheCheckoutWouldSubstituteAGeneratorFromADifferentVersionLine() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.5.0"); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.CodeGeneration.TypeScript", "13.4.0"); - - // The generator is a first-party Aspire.Hosting* reference, so repository mode builds it from - // src/ and discards the version it was pinned to. A third-party package name matches nothing - // under src/, so the request-level guard finds no substitution and returns clean — yet the - // document this run would publish carries the requested version while describing the shape a - // 13.4.0 generator emits. - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0"); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Null(rpcClient.LastExportRequest); - Assert.Empty(interactionService.DisplayedRawText); - } - - [Fact] - public async Task SdkExportAllowsASubstitutedGeneratorAtTheCheckoutVersion() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.CodeGeneration.TypeScript", CheckoutVersionPrefix(provider)); - - // A checkout on this CLI's own version line is the local development case: the generator built - // from src/ is the generator this CLI would have restored, so the export stays supported. - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Contoso.Aspire.Widgets@2.0.0"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "2.0.0"), rpcClient.LastExportRequest); - } - - [Fact] - public async Task SdkExportRejectsFirstPartyPackageVersionSkewEvenWithoutCheckoutSubstitution() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.5.0"); - - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.4.0"); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Null(rpcClient.LastExportRequest); - Assert.Empty(interactionService.DisplayedRawText); - } - - /// - /// The version this CLI reports is overrideable (ASPIRE_CLI_VERSION, the install sidecar), - /// so comparing the request against it alone lets a caller name the checkout whatever they like. - /// The version the checkout actually builds comes from the checkout itself and settles it. - /// - [Fact] - public async Task SdkExportRejectsASubstitutedPackageWhenTheCheckoutBuildsADifferentVersion() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "99.0.0"); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", "13.5.0"); - - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@99.0.0"); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Null(rpcClient.LastExportRequest); - Assert.Empty(interactionService.DisplayedRawText); - } - - /// - /// An ASPIRE_CLI_* override makes the run an emulation of a build this checkout is not. - /// The overrides stay useful everywhere else; they just cannot also decide the label on a - /// document generated from local source. - /// - [Fact] - public async Task SdkExportRejectsASubstitutedPackageWhenTheCliIdentityIsOverridden() + [InlineData("Contoso@not-a-version")] + [InlineData("Contoso@13.5.*")] + [InlineData("Contoso@[13.5.0]")] + public async Task SdkExportRejectsMalformedOrNonExactPackages(string package) { var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); using var provider = CreateProvider( interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.5.0", - identityOverridden: true, - identityVersionForged: true); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", "13.5.0"); + out var workspace, + out var rpcClient, + out _); + using var workspaceLease = workspace; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting.Redis@13.5.0"); + var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package \"{package}\""); Assert.Equal(CliExitCodes.InvalidCommand, exitCode); Assert.Null(rpcClient.LastExportRequest); Assert.Empty(interactionService.DisplayedRawText); } - /// - /// A normally installed CLI can export the core package, which is the command's advertised - /// default invocation. - /// - /// - /// The guard used to test IdentityOverridden, an aggregate that is - /// whenever any identity field came from an environment variable - /// or the install sidecar. Every install route writes a sidecar carrying channel and - /// version, so the aggregate is set on ordinary installs and the guard rejected precisely the - /// CLIs its own error message told callers to use. Only a version this run invented can make - /// the label unverifiable, so that is what the guard tests. - /// [Fact] - public async Task SdkExportOfTheCorePackageAcceptsASidecarSuppliedIdentity() + public async Task SdkExportRejectsCoreVersionDifferentFromTheCli() { var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); using var provider = CreateProvider( interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.5.0", - identityOverridden: true, - identityVersionForged: false); + out var workspace, + out var rpcClient, + out _); + using var workspaceLease = workspace; - var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); - - Assert.Equal(0, exitCode); - var request = Assert.NotNull(rpcClient.LastExportRequest); - Assert.Equal("Aspire.Hosting", request.PackageName); - } - - /// - /// When the checkout cannot say what it builds there is nothing left to check the label against, - /// and an unverifiable label is the failure mode this command exists to prevent. - /// - [Fact] - public async Task SdkExportRejectsASubstitutedPackageWhenTheCheckoutVersionIsUnknown() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", checkoutVersionPrefix: null); - - var checkoutVersion = provider.GetRequiredService().IdentitySdkVersion; - - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{checkoutVersion}"); + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package Aspire.Hosting@0.0.1"); Assert.Equal(CliExitCodes.InvalidCommand, exitCode); Assert.Null(rpcClient.LastExportRequest); - Assert.Empty(interactionService.DisplayedRawText); } - /// - /// Neither scanner honours the requested SDK version — the repository scanner builds - /// src/Aspire.Hosting and the prebuilt scanner loads the assemblies bundled with the CLI - /// — so a core export always describes this CLI. The version guard that enforces that compares - /// the request against the identity, which an override also controls, and the default request is - /// that same identity, so the comparison is vacuous under an override. - /// [Fact] - public async Task SdkExportOfTheCorePackageRejectsAnOverriddenCliIdentity() + public async Task SdkExportUsesStructuredInvalidParametersForUnsupportedLanguage() { var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); + var rpcClient = new ThrowingExportRpcClient(new RemoteInvocationException( + "No code generator found for language: klingon.", + (int)JsonRpcErrorCode.InvalidParams, + errorData: null)); using var provider = CreateProvider( interactionService, - workspace, + out var workspace, rpcClient, - appHostServerProject, - identityVersion: "99.0.0", - identityOverridden: true, - identityVersionForged: true); + new CapturingAppHostServerProject()); + using var workspaceLease = workspace; - // No --package at all, so this is the default invocation: Aspire.Hosting at the identity - // version. Without the guard this publishes the current core surface as 99.0.0. - var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); + var exitCode = await InvokeAsync(provider, "sdk export --language klingon"); Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Null(rpcClient.LastExportRequest); Assert.Empty(interactionService.DisplayedRawText); + Assert.Contains( + interactionService.DisplayedErrors, + error => error.Contains("klingon", StringComparison.Ordinal)); } - /// - /// Repository mode is entered through ASPIRE_REPO_ROOT, which is not an identity field, - /// so an installed CLI pointed at a checkout on another version line has an entirely honest - /// identity and no override in effect. The generated scanner always project-references - /// src/Aspire.Hosting, so what it exports is the checkout's core surface under the - /// installed CLI's number. - /// [Fact] - public async Task SdkExportOfTheCorePackageRejectsACheckoutOnAnotherVersionLine() + public async Task SdkExportRpcFailureWritesNoPartialDocument() { var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); + var rpcClient = new ThrowingExportRpcClient( + new RemoteInvocationException("AppHost export failed.", 0, errorData: null)); using var provider = CreateProvider( interactionService, - workspace, + out var workspace, rpcClient, - appHostServerProject, - identityVersion: "13.4.0"); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); + new CapturingAppHostServerProject()); + using var workspaceLease = workspace; var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Null(rpcClient.LastExportRequest); + Assert.Equal(CliExitCodes.FailedToBuildArtifacts, exitCode); Assert.Empty(interactionService.DisplayedRawText); } - /// - /// The core package is matched case-insensitively but resolved through the filesystem, and the - /// generated scanner project-references src/Aspire.Hosting under that exact spelling - /// regardless of how the caller spelled it. A lookup under the caller's spelling would miss on - /// a case-sensitive filesystem and skip the check while the scanner still built the checkout. - /// [Fact] - public async Task SdkExportOfTheCorePackageRejectsACheckoutOnAnotherVersionLineWhateverTheCasing() + public async Task SdkExportHasNoSourceOrOutputOptions() { var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); using var provider = CreateProvider( interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.4.0"); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); + out var workspace, + out var rpcClient, + out _); + using var workspaceLease = workspace; - // The version has to match the identity or the earlier core guard rejects it for a different - // reason, which would hide whether the substitution lookup found anything. - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package aspire.hosting@13.4.0"); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Null(rpcClient.LastExportRequest); - Assert.Empty(interactionService.DisplayedRawText); - } - - /// - /// Rejecting a bad request under any spelling is half of it. The exported document records the - /// package name verbatim as the identity documentation is keyed on, and the scanner builds - /// src/Aspire.Hosting whatever was typed, so a good request has to be published under the - /// canonical id rather than the caller's spelling. - /// - [Fact] - public async Task SdkExportOfTheCorePackageIsPublishedUnderItsCanonicalNameWhateverTheCasing() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.5.0"); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); - - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package aspire.hosting@13.5.0"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "Aspire.Hosting", "13.5.0"), rpcClient.LastExportRequest); - - var stdout = Assert.Single(interactionService.DisplayedRawText, entry => entry.ConsoleOverride == ConsoleOutput.Standard); - using var document = JsonDocument.Parse(stdout.Text); - Assert.Equal("Aspire.Hosting", document.RootElement.GetProperty("package").GetProperty("name").GetString()); - } - - /// - /// The same checkout on the same version line is exactly what the label claims, so it exports. - /// - [Fact] - public async Task SdkExportOfTheCorePackageFromAMatchingCheckoutSucceeds() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - appHostServerProject, - identityVersion: "13.5.0"); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting", "13.5.0"); - - var exitCode = await InvokeAsync(provider, "sdk export --language typescript"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal("Aspire.Hosting", rpcClient.LastExportRequest?.PackageName); - Assert.Equal("13.5.0", rpcClient.LastExportRequest?.PackageVersion); - } - - [Fact] - public async Task SdkExportForAThirdPartyPackageIsUnaffectedByCheckoutSubstitution() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName); - var rpcClient = new StubExportRpcClient(); - using var provider = CreateProvider(interactionService, workspace, rpcClient, appHostServerProject); - appHostServerProject.AddLocalProjectSubstitution("Aspire.Hosting.Redis", CheckoutVersionPrefix(provider)); - - // A Community Toolkit integration is never replaced by a repository project, so it restores - // at the requested version even from a checkout and must keep exporting. var exitCode = await InvokeAsync( provider, - "sdk export --language typescript --package CommunityToolkit.Aspire.Hosting.ActiveMQ@13.4.0"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0"), rpcClient.LastExportRequest); - } - - /// - /// A bare NuGet version is a minimum, not an equality, so a package that is missing from the feed - /// restores as the next one up and the export is published under a version it does not describe. - /// Both the requested package and the code generation package are part of the exported surface, so - /// both need exact restore ranges. - /// - [Fact] - public async Task SdkExportPinsTheRequestedAndCodeGenerationPackagesToExactVersions() - { - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appHostServerProject = new CapturingAppHostServerProject(workspace.WorkspaceRoot.FullName); - using var provider = CreateProvider(interactionService, workspace, new StubExportRpcClient(), appHostServerProject); - var packageVersion = provider.GetRequiredService().IdentitySdkVersion; - - var exitCode = await InvokeAsync(provider, $"sdk export --language typescript --package Aspire.Hosting.Redis@{packageVersion}"); - - Assert.Equal(CliExitCodes.Success, exitCode); - - var requested = Assert.Single(appHostServerProject.Integrations, integration => integration.Name == "Aspire.Hosting.Redis"); - Assert.True(requested.RequireExactVersion); - - var codeGeneration = Assert.Single( - appHostServerProject.Integrations, - integration => integration.Name.Contains("CodeGeneration", StringComparison.OrdinalIgnoreCase)); - Assert.True(codeGeneration.RequireExactVersion); - } - - [Fact] - public async Task SdkExportWithUnsupportedLanguageReturnsInvalidCommand() - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out _, new ThrowingExportRpcClient( - new NotSupportedException("The 'Go' code generator does not implement IApiReferenceExporter."))); - using var _2 = workspace; - - var exitCode = await InvokeAsync(provider, "sdk export --language go --package Aspire.Hosting@13.5.0"); - - Assert.Equal(CliExitCodes.InvalidCommand, exitCode); - Assert.Empty(interactionService.DisplayedRawText); - } - - [Fact] - public async Task SdkExportWhenRpcFailsReturnsFailureAndWritesNothingToStdout() - { - var interactionService = new TestInteractionService(); - using var provider = CreateProvider(interactionService, out var workspace, out _, new ThrowingExportRpcClient( - new RemoteInvocationException("apphost blew up", 0, errorData: null))); - using var _2 = workspace; - - var exitCode = await InvokeAsync(provider, "sdk export --language typescript --package Aspire.Hosting@13.5.0"); + "sdk export --language typescript --source custom-feed"); Assert.NotEqual(CliExitCodes.Success, exitCode); - - // A partial document is worse than none: a consumer would publish it as if it were complete. - Assert.Empty(interactionService.DisplayedRawText); - } - - [Fact] - public async Task SdkDumpJsonPayloadIsUnchangedByTheSharedPreparationExtraction() - { - // sdk export and sdk dump now share preparation code but nothing else. This lives beside the - // export tests because it guards the extraction, not dump's own behaviour: dump must keep - // producing its existing capabilities payload and must not be routed through the canonical - // exporter. - var interactionService = new TestInteractionService(); - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var rpcClient = new CapabilitiesRpcClient(); - using var provider = CreateProvider( - interactionService, - workspace, - rpcClient, - new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName)); - - var exitCode = await InvokeAsync(provider, "sdk dump --format json Aspire.Hosting.Redis@13.5.0"); - - Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(["Aspire.Hosting.Redis"], rpcClient.LastAssemblyNames); - - var stdout = Assert.Single(interactionService.DisplayedRawText); - using var document = JsonDocument.Parse(stdout.Text); - - // The capabilities shape, not the canonical export schema. - Assert.False(document.RootElement.TryGetProperty("schemaVersion", out _)); - Assert.True(document.RootElement.TryGetProperty("Capabilities", out _)); + Assert.Null(rpcClient.LastExportRequest); } private static async Task InvokeAsync(ServiceProvider provider, string commandLine) @@ -848,37 +227,25 @@ private ServiceProvider CreateProvider( TestInteractionService interactionService, out TemporaryWorkspace workspace, out StubExportRpcClient rpcClient, - IAppHostRpcClient? overrideRpcClient = null) + out CapturingAppHostServerProject project) { workspace = TemporaryWorkspace.CreateForCli(outputHelper); rpcClient = new StubExportRpcClient(); - return CreateProvider( - interactionService, - workspace, - overrideRpcClient ?? rpcClient, - new FakeSucceedingAppHostServerProject(workspace.WorkspaceRoot.FullName)); + project = new CapturingAppHostServerProject(); + return CreateProvider(interactionService, out _, rpcClient, project, workspace); } private ServiceProvider CreateProvider( TestInteractionService interactionService, - TemporaryWorkspace workspace, + out TemporaryWorkspace workspace, IAppHostRpcClient rpcClient, IAppHostServerProject appHostServerProject, - string? identityVersion = null, - bool identityOverridden = false, - bool identityVersionForged = false) + TemporaryWorkspace? existingWorkspace = null) { + workspace = existingWorkspace ?? TemporaryWorkspace.CreateForCli(outputHelper); var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper, options => { options.InteractionServiceFactory = _ => interactionService; - if (identityVersion is not null || identityOverridden || identityVersionForged) - { - options.CliExecutionContextFactory = _ => TestExecutionContextHelper.CreateExecutionContext( - workspace.WorkspaceRoot, - identityVersion: identityVersion, - identityOverridden: identityOverridden, - identityVersionForged: identityVersionForged); - } }); services.AddSingleton(new TestAppHostServerProjectFactory @@ -893,24 +260,15 @@ private ServiceProvider CreateProvider( return services.BuildServiceProvider(); } - /// - /// The Major.Minor.Patch a checkout matching this CLI's identity would build. Tests that - /// exercise the honest local-development path need the substitution to agree with the identity. - /// - private static string CheckoutVersionPrefix(ServiceProvider provider) - { - var identity = SemVersion.Parse( - provider.GetRequiredService().IdentitySdkVersion, - SemVersionStyles.Any); - - return $"{identity.Major}.{identity.Minor}.{identity.Patch}"; - } - private sealed class StubExportRpcClient : FakeAppHostRpcClient { public (string Language, string PackageName, string PackageVersion)? LastExportRequest { get; private set; } - public override Task ExportApiAsync(string languageId, string packageName, string packageVersion, CancellationToken cancellationToken) + public override Task ExportApiAsync( + string languageId, + string packageName, + string packageVersion, + CancellationToken cancellationToken) { LastExportRequest = (languageId, packageName, packageVersion); @@ -922,7 +280,7 @@ public override Task ExportApiAsync(string languageId, string packa "modules": [], "declarations": [] } - """); + """.ReplaceLineEndings("\r\n")); return Task.FromResult(document.RootElement.Clone()); } @@ -930,26 +288,17 @@ public override Task ExportApiAsync(string languageId, string packa private sealed class ThrowingExportRpcClient(Exception exception) : FakeAppHostRpcClient { - public override Task ExportApiAsync(string languageId, string packageName, string packageVersion, CancellationToken cancellationToken) + public override Task ExportApiAsync( + string languageId, + string packageName, + string packageVersion, + CancellationToken cancellationToken) => Task.FromException(exception); } - private sealed class CapabilitiesRpcClient : FakeAppHostRpcClient - { - public IReadOnlyList? LastAssemblyNames { get; private set; } - - public override Task GetCapabilitiesForAssembliesAsync(IReadOnlyList assemblyNames, CancellationToken cancellationToken) - { - LastAssemblyNames = assemblyNames; - return Task.FromResult(new CapabilitiesInfo()); - } - } - - private sealed class CapturingAppHostServerProject(string appDirectoryPath) : IAppHostServerProject + private sealed class CapturingAppHostServerProject : IAppHostServerProject { - public string AppDirectoryPath { get; } = appDirectoryPath; - - public string? PackageSourceOverride { get; private set; } + public string AppDirectoryPath => Environment.CurrentDirectory; public IReadOnlyList Integrations { get; private set; } = []; @@ -962,7 +311,6 @@ public Task PrepareAsync( string? packageSourceOverride = null, CancellationToken cancellationToken = default) { - PackageSourceOverride = packageSourceOverride; Integrations = [.. integrations]; return Task.FromResult(new AppHostServerPrepareResult(Success: true, Output: null)); } @@ -973,6 +321,6 @@ public Task RunAsync( string[]? additionalArgs, bool debug, AppHostServerRunControl? runControl) - => throw new NotSupportedException("Run should not be invoked when using a fake codegen session."); + => throw new NotSupportedException("Run should not be invoked by this test."); } } diff --git a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs index b4e6d5c6432..3ed71abb0ba 100644 --- a/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/SdkDumpCommandTests.cs @@ -334,67 +334,6 @@ public void FormatCi_IncludesExportedValues() Assert.Contains("TestCatalog.Default: test/string = \"你好\"", output); } - [Fact] - public void FormatCi_MarksNullableCapabilityParameters() - { - var capabilities = new CapabilitiesInfo - { - Capabilities = - [ - new CapabilityInfo - { - CapabilityId = "Pkg/withNullable", - Parameters = - [ - new Aspire.Cli.Commands.Sdk.ParameterInfo - { - Name = "name", - IsNullable = true, - Type = new TypeRefInfo { TypeId = "string" } - } - ], - ReturnType = new TypeRefInfo { TypeId = "void" } - } - ] - }; - - var output = InvokeFormatter("FormatCi", capabilities); - - Assert.Contains("Pkg/withNullable(name: string?) -> void", output); - } - - [Theory] - [InlineData("withHostPort", "Pkg/withRedisCommanderHostPort(port: number) -> void [method=withHostPort]")] - [InlineData("withRedisCommanderHostPort", "Pkg/withRedisCommanderHostPort(port: number) -> void")] - [InlineData("", "Pkg/withRedisCommanderHostPort(port: number) -> void")] - public void FormatCi_NamesTheProjectedMethodOnlyWhenItDiffersFromTheCapabilityId(string methodName, string expectedLine) - { - var capabilities = new CapabilitiesInfo - { - Capabilities = - [ - new CapabilityInfo - { - CapabilityId = "Pkg/withRedisCommanderHostPort", - MethodName = methodName, - Parameters = - [ - new Aspire.Cli.Commands.Sdk.ParameterInfo - { - Name = "port", - Type = new TypeRefInfo { TypeId = "number" } - } - ], - ReturnType = new TypeRefInfo { TypeId = "void" } - } - ] - }; - - var output = InvokeFormatter("FormatCi", capabilities); - - Assert.Contains(expectedLine, output, StringComparison.Ordinal); - } - [Fact] public void FormatPretty_IncludesExportedValues() { @@ -407,119 +346,6 @@ public void FormatPretty_IncludesExportedValues() Assert.Contains("\"你好\"", output); } - /// - /// sdk dump reports the versions it was asked to scan, not the versions NuGet - /// resolved. That is deliberate and different from sdk export, which publishes documents - /// keyed on the version and therefore pins the restore. - /// - /// - /// Nothing consumes packages as a resolved identity: --format ci — the format the - /// checked-in *.ats.txt baselines use — omits the block entirely, and - /// generate-ats-diffs.yml passes .csproj paths, which carry no version at all. - /// - [Fact] - public void SdkDumpRecordsTheRequestedPackageVersionRatherThanTheResolvedOne() - { - Assert.True(SdkCommandPreparation.TryParseIntegrationArgument( - "Aspire.Hosting.Redis@13.4.0", - requireExactVersion: false, - out var reference, - out _, - out _)); - - // The restore is a NuGet minimum, so 13.4.1 can satisfy it while `packages` still says - // 13.4.0. Callers that need the two to agree use `sdk export`. - Assert.False(reference!.RequireExactVersion); - Assert.Equal("13.4.0", reference.GetRestoreVersionRange(forceExact: false)); - - var capabilities = new CapabilitiesInfo - { - Packages = [new PackageInfo { Name = reference.Name, Version = reference.Version! }] - }; - - using var document = JsonDocument.Parse(InvokeFormatter("FormatJson", capabilities)); - var package = Assert.Single(document.RootElement.GetProperty("Packages").EnumerateArray()); - Assert.Equal("Aspire.Hosting.Redis", package.GetProperty("Name").GetString()); - Assert.Equal("13.4.0", package.GetProperty("Version").GetString()); - } - - /// - /// NuGet package versions may carry a fourth Revision segment that semantic versioning - /// cannot express, so a semver-only parse would reject shipping packages such as - /// 5.2.9.0. Argument parsing has to accept them and normalize the way NuGet does. - /// - [Theory] - [InlineData("5.2.9.0", "5.2.9")] - [InlineData("1.2.3.4", "1.2.3.4")] - [InlineData("1.2.3.4-beta.1", "1.2.3.4-beta.1")] - [InlineData("01.02.03.00", "1.2.3")] - [InlineData("1.2.3.4-beta.01", "1.2.3.4-beta.01")] - [InlineData("1.2.3.0+sha.abc", "1.2.3+sha.abc")] - public void FourSegmentPackageVersionsAreAcceptedAndNormalizedLikeNuGet(string requested, string expected) - { - Assert.True(SdkCommandPreparation.TryParseIntegrationArgument( - $"Aspire.Hosting.Redis@{requested}", - requireExactVersion: true, - out var reference, - out _, - out var errorMessage), errorMessage); - - Assert.Equal(expected, reference!.Version); - } - - /// - /// Accepting a fourth segment must not open the door to the floating and range syntax that - /// sdk export deliberately refuses, since neither pins a single document version. - /// - [Theory] - [InlineData("1.2.3.*")] - [InlineData("[1.0.0.0,2.0.0.0)")] - [InlineData("1.2.3.4.5")] - [InlineData("1.2.3.-1")] - [InlineData("1.2.3.4-")] - [InlineData("1.2.3.4+")] - [InlineData("1.2.3.4-.")] - [InlineData("1.2.3.4-beta_1")] - public void FloatingAndRangeVersionsAreStillRejected(string requested) - { - Assert.False(SdkCommandPreparation.TryParseIntegrationArgument( - $"Aspire.Hosting.Redis@{requested}", - requireExactVersion: true, - out _, - out _, - out var errorMessage)); - - Assert.Contains($"Invalid version '{requested}'", errorMessage); - } - - /// - /// The checked-in *.ats.txt baselines are produced with --format ci, which carries - /// no package versions at all. That is what keeps the requested-version semantics above from - /// reaching a version-keyed artifact. - /// - [Fact] - public void SdkDumpCiFormatCarriesNoPackageVersions() - { - var capabilities = new CapabilitiesInfo - { - Packages = [new PackageInfo { Name = "Aspire.Hosting.Redis", Version = "13.4.0" }] - }; - - var sections = InvokeFormatter("FormatCi", capabilities) - .Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries) - .Where(line => line.StartsWith('#')) - .ToArray(); - - Assert.Equal( - [ - "# Aspire Type System Capabilities", - "# Generated by: aspire sdk dump --format ci", - "# Handle Types", - "# Capabilities" - ], - sections); - } - private static string InvokeFormatter(string methodName, CapabilitiesInfo capabilities) { var method = typeof(SdkDumpCommand).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic); diff --git a/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs b/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs index 109650b6dfa..646321f32d6 100644 --- a/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs +++ b/tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs @@ -29,43 +29,6 @@ public void ProjectReference_HasProjectPathAndNoVersion() Assert.Equal("/path/to/MyIntegration.csproj", reference.ProjectPath); } - /// - /// A caller can write a NuGet range directly. Pinning it again would produce [[13.2.0]], - /// which NuGet rejects, so an already-bracketed version has to pass through untouched no matter - /// which side asked for exactness. - /// - [Theory] - [InlineData("[13.2.0]")] - [InlineData("[13.2.0,13.3.0)")] - [InlineData("(13.2.0,)")] - public void GetRestoreVersionRange_LeavesAnExplicitRangeAlone(string version) - { - Assert.Equal(version, IntegrationReference.FromPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: false)); - Assert.Equal(version, IntegrationReference.FromPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: true)); - Assert.Equal(version, IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: false)); - Assert.Equal(version, IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", version).GetRestoreVersionRange(forceExact: true)); - } - - [Fact] - public void GetRestoreVersionRange_PinsOnlyWhenExactnessIsAskedFor() - { - var floating = IntegrationReference.FromPackage("Aspire.Hosting.Redis", "13.2.0"); - var exact = IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", "13.2.0"); - - Assert.Equal("13.2.0", floating.GetRestoreVersionRange(forceExact: false)); - Assert.Equal("[13.2.0]", floating.GetRestoreVersionRange(forceExact: true)); - Assert.Equal("[13.2.0]", exact.GetRestoreVersionRange(forceExact: false)); - Assert.Equal("[13.2.0]", exact.GetRestoreVersionRange(forceExact: true)); - } - - [Fact] - public void GetRestoreVersionRange_ThrowsForAProjectReference() - { - var reference = IntegrationReference.FromProject("MyIntegration", "/path/to/MyIntegration.csproj"); - - Assert.Throws(() => reference.GetRestoreVersionRange(forceExact: false)); - } - [Fact] public void GetIntegrationReferences_DetectsCsprojAsProjectReference() { diff --git a/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs b/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs index 8f4d53b1d30..44b61a92264 100644 --- a/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs @@ -177,6 +177,29 @@ public async Task CreateProjectFiles_SkipsAspireIntegrationAnalyzerReferences() Assert.Equal("true", skipAnalyzersElement.Value); } + [Fact] + public async Task CreateProjectFiles_ExactAspirePackageRestoresInsteadOfUsingCheckoutProject() + { + var project = CreateProject(); + var integrations = new[] + { + IntegrationReference.FromPackage("Aspire.Hosting.Redis", "[13.1.0]"), + IntegrationReference.FromPackage("Aspire.Hosting.PostgreSQL", "13.1.0") + }; + + var (projectPath, _) = await project.CreateProjectFilesAsync(integrations).DefaultTimeout(); + + var document = XDocument.Load(projectPath); + var packageReference = Assert.Single( + document.Descendants("PackageReference"), + element => element.Attribute("Include")?.Value == "Aspire.Hosting.Redis"); + + Assert.Equal("[13.1.0]", packageReference.Attribute("Version")?.Value); + Assert.DoesNotContain( + document.Descendants("PackageReference"), + element => element.Attribute("Include")?.Value == "Aspire.Hosting.PostgreSQL"); + } + [Fact] public void ProjectModelPath_IsStableForSameAppPath() { diff --git a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs b/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs deleted file mode 100644 index 4f2064947f3..00000000000 --- a/tests/Aspire.Cli.Tests/Projects/DotNetBasedAppHostServerPackageReferenceTests.cs +++ /dev/null @@ -1,449 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Xml.Linq; -using Aspire.Cli.Configuration; -using Aspire.Cli.Projects; -using Aspire.Cli.Tests.Mcp; -using Aspire.Cli.Tests.TestServices; -using Aspire.Cli.Tests.Utils; -using Aspire.Hosting; -using Microsoft.Extensions.Logging.Abstractions; - -namespace Aspire.Cli.Tests.Projects; - -/// -/// The generated capability scanner writes its own Directory.Packages.props that turns central -/// package management on so transitive dependencies pick up the repo's pinned versions. Central package -/// management rejects an inline Version attribute on a PackageReference with NU1008, which -/// made the scanner fail to build for any integration that lives outside the repo — the exact case -/// aspire sdk export hits when it is pointed at a third-party package such as a Community Toolkit -/// integration. -/// -public class DotNetBasedAppHostServerPackageReferenceTests(ITestOutputHelper outputHelper) -{ - [Fact] - public async Task CreateProjectFiles_PinsOutOfRepoIntegrationsWithVersionOverride() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - var projectModelPath = Path.Combine(appPath, ".aspire_server"); - - var project = CreateProject(appPath, projectModelPath); - - // There is no src/CommunityToolkit.Aspire.Hosting.ActiveMQ under the fake repo root, so this - // integration takes the package path rather than the project-reference path. - await project.CreateProjectFilesAsync( - [IntegrationReference.FromPackage("CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0")]); - - var packagesProps = XDocument.Load(Path.Combine(projectModelPath, "Directory.Packages.props")); - Assert.Equal( - "true", - packagesProps.Descendants("ManagePackageVersionsCentrally").Single().Value); - - var reference = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")) - .Descendants("PackageReference") - .Single(element => element.Attribute("Include")?.Value == "CommunityToolkit.Aspire.Hosting.ActiveMQ"); - - Assert.Equal("13.4.0", reference.Attribute("VersionOverride")?.Value); - Assert.Null(reference.Attribute("Version")); - } - - /// - /// Asserting on the generated XML alone cannot catch a change in how NuGet treats - /// VersionOverride under central package management. This restores the generated project - /// for real against an offline folder feed, with a central package list that deliberately has no - /// entry for the out-of-repo integration, so a regression surfaces as NU1008 or NU1010. - /// - [Fact] - public async Task CreateProjectFiles_ProducesAProjectThatRestores() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - var projectModelPath = Path.Combine(appPath, ".aspire_server"); - var feedPath = Path.Combine(appPath, "feed"); - Directory.CreateDirectory(feedPath); - - const string IntegrationPackage = "CommunityToolkit.Aspire.Hosting.ActiveMQ"; - - // The template always references these two without a version, so they have to resolve - // through the central list the way they do in the real repo. - OfflineNuGetFeed.CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); - OfflineNuGetFeed.CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); - OfflineNuGetFeed.CreateStubPackage(feedPath, IntegrationPackage, "13.4.0"); - - // Mirrors the real repo: a central list that pins first-party dependencies but knows nothing - // about a Community Toolkit integration. - await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), """ - - - - - - - """); - - var project = CreateProject(appPath, projectModelPath); - - await project.CreateProjectFilesAsync( - [IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")]); - - var (exitCode, output) = await OfflineNuGetFeed.RestoreAsync( - Path.Combine(projectModelPath, "AppHostServer.csproj"), - feedPath); - - outputHelper.WriteLine(output); - - // NU1008 is the inline Version attribute this fix replaced; NU1010 is the failure mode that - // would appear if VersionOverride stopped satisfying the central list requirement. - Assert.DoesNotContain("NU1008", output, StringComparison.Ordinal); - Assert.DoesNotContain("NU1010", output, StringComparison.Ordinal); - Assert.Equal(0, exitCode); - } - - [Fact] - public async Task PrepareWritesPackageProbeManifestForOutOfRepoIntegrations() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - var projectModelPath = Path.Combine(appPath, ".aspire_server"); - var packageDirectory = Path.Combine(appPath, "packages"); - Directory.CreateDirectory(packageDirectory); - - var primaryAssemblyPath = Path.Combine(packageDirectory, "Contoso.Hosting.dll"); - var secondaryAssemblyPath = Path.Combine(packageDirectory, "Contoso.Hosting.Extras.dll"); - var satelliteAssemblyPath = Path.Combine(packageDirectory, "fr", "Contoso.Hosting.resources.dll"); - Directory.CreateDirectory(Path.GetDirectoryName(satelliteAssemblyPath)!); - await File.WriteAllTextAsync(primaryAssemblyPath, string.Empty); - await File.WriteAllTextAsync(secondaryAssemblyPath, string.Empty); - await File.WriteAllTextAsync(satelliteAssemblyPath, string.Empty); - - var runner = new TestDotNetCliRunner - { - BuildAsyncCallback = (_, _, _, _) => - { - File.WriteAllLines( - Path.Combine(projectModelPath, "package-probe-sources.txt"), - [primaryAssemblyPath, secondaryAssemblyPath, satelliteAssemblyPath]); - File.WriteAllLines( - Path.Combine(projectModelPath, "package-probe-metadata.txt"), - [ - "Contoso.Aspire.MetaPackage|1.2.3|runtime", - "Contoso.Aspire.MetaPackage|1.2.3|runtime", - "Contoso.Aspire.MetaPackage|1.2.3|resources" - ]); - File.WriteAllLines( - Path.Combine(projectModelPath, "package-probe-targets.txt"), - [ - "Contoso.Hosting.dll", - "Contoso.Hosting.Extras.dll", - "fr/Contoso.Hosting.resources.dll" - ]); - - return 0; - } - }; - var processExecutionFactory = new TestProcessExecutionFactory(); - var project = CreateProject(appPath, projectModelPath, runner, processExecutionFactory); - - var result = await project.PrepareAsync( - "13.5.0", - [IntegrationReference.FromExactPackage("Contoso.Aspire.MetaPackage", "1.2.3")]); - - Assert.True(result.Success); - - var manifestPath = Path.Combine(projectModelPath, IntegrationPackageProbeManifest.FileName); - Assert.True(File.Exists(manifestPath)); - - var manifest = IntegrationPackageProbeManifest.Load(manifestPath); - Assert.True(manifest.TryGetRuntimeAssemblyNamesForPackage("contoso.aspire.metapackage", out var canonicalPackageId, out var assemblyNames)); - Assert.Equal("Contoso.Aspire.MetaPackage", canonicalPackageId); - Assert.Equal(["Contoso.Hosting", "Contoso.Hosting.Extras"], assemblyNames); - Assert.Contains( - manifest.ManagedAssemblies, - assembly => assembly.Name == "Contoso.Hosting.resources" && - assembly.Culture == "fr" && - assembly.PackageId == "Contoso.Aspire.MetaPackage" && - assembly.PackageVersion == "1.2.3"); - - var runResult = await project.RunAsync( - Environment.ProcessId, - environmentVariables: null, - additionalArgs: null, - debug: false, - runControl: null); - await using var execution = runResult.Execution; - - Assert.Equal(manifestPath, processExecutionFactory.LastEnvironmentVariables?[KnownConfigNames.IntegrationProbeManifestPath]); - } - - /// - /// aspire sdk export publishes documentation keyed on the requested version, so the - /// restore has to fail when that version is unavailable rather than resolve to a later one. - /// - [Fact] - public async Task CreateProjectFiles_PinsExactIntegrationsToASingleVersionRange() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - var projectModelPath = Path.Combine(appPath, ".aspire_server"); - - var project = CreateProject(appPath, projectModelPath); - - await project.CreateProjectFilesAsync( - [ - IntegrationReference.FromExactPackage("CommunityToolkit.Aspire.Hosting.ActiveMQ", "13.4.0"), - IntegrationReference.FromPackage("CommunityToolkit.Aspire.Hosting.Dapr", "13.4.0") - ]); - - var references = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")) - .Descendants("PackageReference") - .ToDictionary(element => element.Attribute("Include")!.Value, element => element.Attribute("VersionOverride")?.Value); - - Assert.Equal("[13.4.0]", references["CommunityToolkit.Aspire.Hosting.ActiveMQ"]); - - // Everything else keeps the minimum-version form the run and dump paths have always used. - Assert.Equal("13.4.0", references["CommunityToolkit.Aspire.Hosting.Dapr"]); - } - - /// - /// The generated scanner replaces a first-party Aspire.Hosting.* package reference with the - /// matching repository project and drops the requested version, so a caller that publishes - /// artifacts keyed on that version has to be able to see the substitution coming. - /// - [Fact] - public void GetLocalProjectSubstitution_ReportsOnlyFirstPartyProjectsThatExist() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - - var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); - Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); - File.WriteAllText(redisProjectPath, ""); - - var project = CreateProject(appPath, Path.Combine(appPath, ".aspire_server")); - - Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("Aspire.Hosting.Redis")?.ProjectPath); - - // No src/Aspire.Hosting.Qdrant in this checkout, so the package really is restored. - Assert.Null(project.GetLocalProjectSubstitution("Aspire.Hosting.Qdrant")); - - // Third-party integrations are never substituted, even when a same-named folder exists. - Assert.Null(project.GetLocalProjectSubstitution("CommunityToolkit.Aspire.Hosting.ActiveMQ")); - } - - /// - /// A NuGet package id is case-insensitive, but this resolves one through the filesystem, which - /// is not on Linux. Probing the caller's spelling let it decide whether the checkout was - /// substituted at all: aspire.hosting.redis found nothing there while macOS and Windows - /// found src/Aspire.Hosting.Redis, so a caller that publishes version-keyed artifacts saw - /// no substitution to guard against on the one platform the docs pipeline runs on. - /// - [Fact] - public void GetLocalProjectSubstitution_ResolvesFirstPartyProjectsUnderAnyCasing() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - - var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); - Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); - File.WriteAllText(redisProjectPath, ""); - - var project = CreateProject(appPath, Path.Combine(appPath, ".aspire_server")); - - // The on-disk spelling, not the caller's. Asserting the canonical path is what makes this - // meaningful on a case-insensitive filesystem too, where probing the caller's spelling - // succeeds but hands back a path spelled the way the request was. - Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("aspire.hosting.redis")?.ProjectPath); - Assert.Equal(redisProjectPath, project.GetLocalProjectSubstitution("ASPIRE.HOSTING.REDIS")?.ProjectPath); - - // Case-insensitive matching still only reports what the checkout actually contains. - Assert.Null(project.GetLocalProjectSubstitution("aspire.hosting.qdrant")); - } - - /// - /// The substitution check and the generated project have to make the same decision, or a caller - /// that was told nothing would be substituted still gets a scanner built from the checkout. - /// - [Fact] - public async Task CreateProjectFiles_SubstitutesTheCheckoutProjectUnderAnyCasing() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - var projectModelPath = Path.Combine(appPath, ".aspire_server"); - - var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); - Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); - File.WriteAllText(redisProjectPath, ""); - - var project = CreateProject(appPath, projectModelPath); - - await project.CreateProjectFilesAsync( - [IntegrationReference.FromExactPackage("aspire.hosting.redis", "13.4.0")]); - - var document = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")); - - Assert.Equal( - [redisProjectPath], - document.Descendants("ProjectReference").Select(element => element.Attribute("Include")!.Value)); - - // No package reference for the integration: the checkout supplies it, which is exactly what - // GetLocalProjectSubstitution reports to callers that publish version-keyed artifacts. The - // two the template always carries are all that is left. - Assert.Equal( - ["StreamJsonRpc", "Google.Protobuf"], - document.Descendants("PackageReference").Select(element => element.Attribute("Include")!.Value)); - } - - /// - /// The version a checkout builds has to come from the checkout, because the version this CLI - /// reports is overrideable. eng/Versions.props is where the repository states it. - /// - [Fact] - public void GetLocalProjectSubstitution_ReportsTheVersionTheCheckoutBuilds() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - - var redisProjectPath = Path.Combine(appPath, "src", "Aspire.Hosting.Redis", "Aspire.Hosting.Redis.csproj"); - Directory.CreateDirectory(Path.GetDirectoryName(redisProjectPath)!); - File.WriteAllText(redisProjectPath, ""); - - var project = CreateProject(appPath, Path.Combine(appPath, ".aspire_server")); - - // No eng/Versions.props yet, so the checkout cannot say what it builds and callers that - // publish version-keyed artifacts have to treat the substitution as unverifiable. - Assert.Null(project.GetLocalProjectSubstitution("Aspire.Hosting.Redis")?.CheckoutVersionPrefix); - - Directory.CreateDirectory(Path.Combine(appPath, "eng")); - File.WriteAllText(Path.Combine(appPath, "eng", "Versions.props"), """ - - - 13 - 5 - 0 - - - """); - - var withVersions = CreateProject(appPath, Path.Combine(appPath, ".aspire_server_versioned")); - - Assert.Equal("13.5.0", withVersions.GetLocalProjectSubstitution("Aspire.Hosting.Redis")?.CheckoutVersionPrefix); - } - - /// - /// A first-party package name does not mean the checkout can supply it. Without a matching - /// project under src/ the reference is dropped from the generated project, so a - /// nonexistent package scanned clean and exported an empty module. A reference that demands an - /// exact version now restores as a real package instead, so the failure surfaces. - /// - /// - /// Only sdk export demands exactness. Everything else keeps dropping the reference, - /// because aspire run and the other scanner callers take their integrations from - /// aspire.config.json, where a version-less entry resolves to this CLI's identity — a version - /// that could never restore from a feed, so failing would break the whole AppHost rather than - /// one integration. - /// - [Fact] - public async Task CreateProjectFiles_FallsBackToAPackageReferenceOnlyForAnExactReference() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - var projectModelPath = Path.Combine(appPath, ".aspire_server"); - - var project = CreateProject(appPath, projectModelPath); - - await project.CreateProjectFilesAsync( - [ - IntegrationReference.FromExactPackage("Aspire.Hosting.NotInThisCheckout", "13.4.0"), - IntegrationReference.FromPackage("Aspire.Hosting.AlsoMissing", "13.4.0") - ]); - - var document = XDocument.Load(Path.Combine(projectModelPath, "AppHostServer.csproj")); - var references = document - .Descendants("PackageReference") - .ToDictionary(element => element.Attribute("Include")!.Value, element => element.Attribute("VersionOverride")?.Value); - - Assert.Equal("[13.4.0]", references["Aspire.Hosting.NotInThisCheckout"]); - Assert.False(references.ContainsKey("Aspire.Hosting.AlsoMissing")); - Assert.Empty(document.Descendants("ProjectReference")); - } - - /// - /// The generated XML cannot show what NuGet does with it. This restores twice against an offline - /// feed that holds 13.4.1 but not the requested 13.4.0: the plain reference silently resolves - /// upward (which is what mislabels an export), and the exact reference fails instead. - /// - [Fact] - public async Task CreateProjectFiles_ExactIntegrationDoesNotFloatToALaterPackage() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var appPath = workspace.WorkspaceRoot.FullName; - var feedPath = Path.Combine(appPath, "feed"); - Directory.CreateDirectory(feedPath); - - const string IntegrationPackage = "Contoso.Aspire.Hosting.ExactVersionProbe"; - - OfflineNuGetFeed.CreateStubPackage(feedPath, "StreamJsonRpc", "1.0.0"); - OfflineNuGetFeed.CreateStubPackage(feedPath, "Google.Protobuf", "1.0.0"); - OfflineNuGetFeed.CreateStubPackage(feedPath, IntegrationPackage, "13.4.1"); - - await File.WriteAllTextAsync(Path.Combine(appPath, "Directory.Packages.props"), """ - - - - - - - """); - - var floatingModelPath = Path.Combine(appPath, ".aspire_server_floating"); - await CreateProject(appPath, floatingModelPath) - .CreateProjectFilesAsync([IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")]); - - var (floatingExitCode, floatingOutput) = await OfflineNuGetFeed.RestoreAsync( - Path.Combine(floatingModelPath, "AppHostServer.csproj"), - feedPath); - outputHelper.WriteLine(floatingOutput); - - // 13.4.0 is a minimum, so NuGet happily hands back 13.4.1 and warns rather than fails. The - // assets file records what was actually resolved, which the console output does not always - // spell out. - Assert.Equal(0, floatingExitCode); - Assert.Contains("NU1603", floatingOutput, StringComparison.Ordinal); - Assert.Contains( - $"{IntegrationPackage}/13.4.1", - await File.ReadAllTextAsync(Path.Combine(floatingModelPath, "obj", "project.assets.json")), - StringComparison.Ordinal); - - var exactModelPath = Path.Combine(appPath, ".aspire_server_exact"); - await CreateProject(appPath, exactModelPath) - .CreateProjectFilesAsync([IntegrationReference.FromExactPackage(IntegrationPackage, "13.4.0")]); - - var (exactExitCode, exactOutput) = await OfflineNuGetFeed.RestoreAsync( - Path.Combine(exactModelPath, "AppHostServer.csproj"), - feedPath); - outputHelper.WriteLine(exactOutput); - - // NU1102 is "package found but not at the requested version", which is the failure a caller - // needs instead of a document labelled 13.4.0 that describes 13.4.1. - Assert.NotEqual(0, exactExitCode); - Assert.Contains("NU1102", exactOutput, StringComparison.Ordinal); - } - - private static DotNetBasedAppHostServerProject CreateProject( - string appPath, - string projectModelPath, - TestDotNetCliRunner? runner = null, - TestProcessExecutionFactory? processExecutionFactory = null) - => new( - appPath, - socketPath: "test.sock", - repoRoot: appPath, - runner ?? new TestDotNetCliRunner(), - MockPackagingServiceFactory.Create(), - processExecutionFactory ?? new TestProcessExecutionFactory(), - new TestEnvironment(), - NullLogger.Instance, - projectModelPath); -} diff --git a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs index 5d34d1e00d0..898530cbad5 100644 --- a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs @@ -44,99 +44,6 @@ public void GenerateIntegrationProjectFile_WithPackagesOnly_ProducesPackageRefer Assert.Empty(doc.Descendants("ProjectReference")); } - [Fact] - public void GenerateIntegrationProjectFile_PinsExactPackagesToASingleVersionRange() - { - var packageRefs = new List - { - IntegrationReference.FromExactPackage("Aspire.Hosting.Redis", "13.2.0"), - IntegrationReference.FromPackage("Aspire.Hosting", "13.2.0") - }; - - var xml = PrebuiltAppHostServer.GenerateIntegrationProjectFile(packageRefs, [], "/tmp/libs"); - var doc = XDocument.Parse(xml); - - var versions = doc.Descendants("PackageReference") - .ToDictionary(e => e.Attribute("Include")!.Value, e => e.Attribute("Version")!.Value); - - // `13.2.0` is a NuGet minimum, so only the bracketed form keeps an unavailable version from - // resolving upward and being documented under the requested number. - Assert.Equal("[13.2.0]", versions["Aspire.Hosting.Redis"]); - Assert.Equal("13.2.0", versions["Aspire.Hosting"]); - } - - /// - /// The generated XML cannot show what NuGet does with it, and the package-only install path never - /// touches the repository scanner, so the pin has to be proven here too. This restores twice - /// against an offline feed that holds 13.4.1 but not the requested 13.4.0. - /// - [Fact] - public async Task GenerateIntegrationProjectFile_ExactPackageDoesNotFloatToALaterPackage() - { - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - var root = workspace.WorkspaceRoot.FullName; - var feedPath = Path.Combine(root, "feed"); - Directory.CreateDirectory(feedPath); - - const string IntegrationPackage = "Contoso.Aspire.Hosting.PrebuiltExactProbe"; - OfflineNuGetFeed.CreateStubPackage(feedPath, IntegrationPackage, "13.4.1"); - - var floatingPath = await WriteIntegrationProjectAsync( - root, - "floating", - IntegrationReference.FromPackage(IntegrationPackage, "13.4.0")); - var (floatingExitCode, floatingOutput) = await OfflineNuGetFeed.RestoreAsync(floatingPath, feedPath); - outputHelper.WriteLine(floatingOutput); - - // NU1603 is NuGet reporting that it resolved something other than what was asked for. The - // assets file records which version won, which the console output does not always spell out. - Assert.Equal(0, floatingExitCode); - Assert.Contains("NU1603", floatingOutput, StringComparison.Ordinal); - Assert.Contains( - $"{IntegrationPackage}/13.4.1", - await File.ReadAllTextAsync(Path.Combine(Path.GetDirectoryName(floatingPath)!, "obj", "project.assets.json")), - StringComparison.Ordinal); - - var exactPath = await WriteIntegrationProjectAsync( - root, - "exact", - IntegrationReference.FromExactPackage(IntegrationPackage, "13.4.0")); - var (exactExitCode, exactOutput) = await OfflineNuGetFeed.RestoreAsync(exactPath, feedPath); - outputHelper.WriteLine(exactOutput); - - // NU1102 is "package found but not at the requested version", which is the failure a caller - // needs instead of a document labelled 13.4.0 that describes 13.4.1. - Assert.NotEqual(0, exactExitCode); - Assert.Contains("NU1102", exactOutput, StringComparison.Ordinal); - } - - /// - /// Writes the prebuilt closure project the way BuildIntegrationClosureManifestAsync does, - /// including the surrounding files that keep the restore from importing the enclosing repository. - /// - private static async Task WriteIntegrationProjectAsync(string root, string name, IntegrationReference reference) - { - var restoreDir = Path.Combine(root, $"integration-restore-{name}"); - Directory.CreateDirectory(restoreDir); - - var projectPath = Path.Combine(restoreDir, "IntegrationClosure.csproj"); - await File.WriteAllTextAsync( - projectPath, - PrebuiltAppHostServer.GenerateIntegrationProjectFile([reference], [], restoreDir)); - - await File.WriteAllTextAsync(Path.Combine(restoreDir, "Directory.Packages.props"), """ - - - false - - - """); - await File.WriteAllTextAsync(Path.Combine(restoreDir, "Directory.Build.props"), ""); - await File.WriteAllTextAsync(Path.Combine(restoreDir, "Directory.Build.targets"), ""); - - return projectPath; - } - [Fact] public void GenerateIntegrationProjectFile_WithProjectRefsOnly_ProducesProjectReferences() { @@ -1244,48 +1151,6 @@ public async Task PrepareAsync_WithPackageReferences_UsesPackageSourceOverride() } } - [Fact] - public async Task PrepareAsync_WithExactPackageReference_PinsBundledRestoreWithoutASourceOverride() - { - // `sdk export` restores through the bundled NuGet helper on an installed CLI, and that path - // never sees the generated closure project. Pin the argument it is actually handed. - using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); - List? restoreArgs = null; - - var (server, executionFactory) = CreatePackageReferenceServer(workspace); - executionFactory.AssertionCallback = (args, _, _, _) => - { - if (args is ["nuget", "restore", ..]) - { - restoreArgs = [.. args]; - } - }; - - var workingDirectory = GetWorkingDirectory(server); - - try - { - var result = await server.PrepareAsync( - "13.4.0", - [ - IntegrationReference.FromExactPackage("CommunityToolkit.Aspire.Hosting.Redis", "13.4.0"), - IntegrationReference.FromPackage("CommunityToolkit.Aspire.Hosting.Dapr", "13.4.0") - ]); - - Assert.True(result.Success); - Assert.NotNull(restoreArgs); - - // No `--source`, so the historical Aspire*-only pinning does not apply and the exactness - // has to come from the reference itself. - Assert.Contains("CommunityToolkit.Aspire.Hosting.Redis,[13.4.0]", restoreArgs!); - Assert.Contains("CommunityToolkit.Aspire.Hosting.Dapr,13.4.0", restoreArgs!); - } - finally - { - DeleteWorkingDirectory(workingDirectory); - } - } - [Fact] public async Task PrepareAsync_WithPackageSourceOverride_AddsNuGetOrgFallbackSource() { @@ -1743,11 +1608,7 @@ await File.WriteAllTextAsync(aspireConfigPath, """ var combined = string.Join('\n', result.Output!.GetLines().Select(static line => line.Line)); Assert.Contains($"--source: {packageSourceOverride}", combined); Assert.Contains("channel: daily", combined); - - // The footer has to show the range restore was actually given. `--source` pins Aspire - // packages, so printing the raw version would send a reader looking for a resolution - // failure that the bracketed form explains immediately. - Assert.Contains("packages: Aspire.Hosting.CodeGeneration.TypeScript [13.4.0-pr.17141.gf142085f]", combined); + Assert.Contains("packages: Aspire.Hosting.CodeGeneration.TypeScript 13.4.0-pr.17141.gf142085f", combined); } finally { @@ -1784,12 +1645,11 @@ public async Task PrepareAsync_RestoreFailure_WithManyPackages_TruncatesPackageL Assert.NotNull(result.Output); var combined = string.Join('\n', result.Output!.GetLines().Select(static line => line.Line)); - // First five packages appear; later ones are collapsed into a count. Versions show the - // effective restore range because `--source` pins Aspire packages exactly. - var packagesLine = Assert.Single(result.Output!.GetLines().Select(static line => line.Line), static line => line.Contains("packages:", StringComparison.Ordinal)); - Assert.Equal( - " packages: Aspire.Hosting.Pkg0 [1.0.0], Aspire.Hosting.Pkg1 [1.0.0], Aspire.Hosting.Pkg2 [1.0.0], Aspire.Hosting.Pkg3 [1.0.0], Aspire.Hosting.Pkg4 [1.0.0], … (+3 more)", - packagesLine); + // First five packages appear; later ones are collapsed into a count. + Assert.Contains("Aspire.Hosting.Pkg0 1.0.0", combined); + Assert.Contains("Aspire.Hosting.Pkg4 1.0.0", combined); + Assert.DoesNotContain("Aspire.Hosting.Pkg5 1.0.0", combined); + Assert.DoesNotContain("Aspire.Hosting.Pkg7 1.0.0", combined); Assert.Contains("(+3 more)", combined); } finally diff --git a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs index 1aeabefd6eb..8e6defbdabe 100644 --- a/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs +++ b/tests/Aspire.Cli.Tests/TestServices/FakeSucceedingAppHostServerProject.cs @@ -16,36 +16,8 @@ internal sealed class FakeSucceedingAppHostServerProject(string appDirectoryPath { public string AppDirectoryPath { get; } = appDirectoryPath; - /// - /// Package names this fake reports as satisfied by a repository project. Mirrors - /// in repository dev mode, where an - /// Aspire.Hosting.* package reference is replaced by the matching project under - /// src/ and the requested package version is discarded. - /// - /// - /// The comparer is ordinal on purpose, which is stricter than the real implementation: that one - /// matches a package id case-insensitively the way a feed does. Requiring the canonical spelling - /// here keeps the command's own canonicalization under test rather than resting on the probe, - /// which matters because implementations that report no - /// substitution at all — the prebuilt scanner — leave the command as the only thing that - /// settles the spelling before the export is labelled. - /// - public Dictionary LocalProjectSubstitutions { get; } = new(StringComparer.Ordinal); - - /// - /// Registers a substitution whose checkout builds , or - /// whose version cannot be established when that is . - /// - public void AddLocalProjectSubstitution(string packageName, string? checkoutVersionPrefix) - => LocalProjectSubstitutions[packageName] = new LocalProjectSubstitution( - Path.Combine("src", packageName, $"{packageName}.csproj"), - checkoutVersionPrefix); - public string GetInstanceIdentifier() => AppDirectoryPath; - public LocalProjectSubstitution? GetLocalProjectSubstitution(string packageName) - => LocalProjectSubstitutions.TryGetValue(packageName, out var substitution) ? substitution : null; - public Task PrepareAsync( string sdkVersion, IEnumerable integrations, diff --git a/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs b/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs deleted file mode 100644 index 28337808214..00000000000 --- a/tests/Aspire.Cli.Tests/Utils/OfflineNuGetFeed.cs +++ /dev/null @@ -1,148 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.IO.Compression; - -namespace Aspire.Cli.Tests.Utils; - -/// -/// A folder-backed NuGet feed built from fabricated packages, plus a restore that can only reach it. -/// -/// -/// Version-range behavior is decided by NuGet, not by the XML the CLI generates, so the only way to -/// prove a pin holds is to restore against a feed whose contents are known exactly. -/// installs into a throwaway global packages folder so the fabricated -/// packages never enter the developer's or the agent's real cache. Reads are not isolated — the real -/// folder is supplied as a fallback so targeting packs still resolve, and NuGet treats a fallback -/// folder as a resolution source — so package ids used with this helper must still not exist on any -/// real feed or in the real cache, or a restore that should fail can succeed from it instead. -/// -internal static class OfflineNuGetFeed -{ - /// - /// Writes a minimal but valid .nupkg for at - /// into . - /// - public static void CreateStubPackage(string feedPath, string id, string version) - { - var stagingPath = Path.Combine(feedPath, $".staging-{id}"); - Directory.CreateDirectory(Path.Combine(stagingPath, "lib", "net10.0")); - - File.WriteAllText(Path.Combine(stagingPath, $"{id}.nuspec"), $""" - - - - {id} - {version} - Stub package for restore tests. - Aspire - - - """); - - File.WriteAllText(Path.Combine(stagingPath, "[Content_Types].xml"), """ - - - - - - - """); - - File.WriteAllBytes(Path.Combine(stagingPath, "lib", "net10.0", $"{id}.dll"), []); - - ZipFile.CreateFromDirectory(stagingPath, Path.Combine(feedPath, $"{id}.{version}.nupkg")); - Directory.Delete(stagingPath, recursive: true); - } - - /// - /// Restores against only, into a - /// throwaway global packages folder. - /// - /// - /// - /// --source replaces every configured source rather than adding one, which is what keeps - /// the restore offline. - /// - /// - /// --packages then keeps the fabricated packages out of the real global packages folder. - /// Without it they are installed under their stated ids for good — NuGet never re-downloads a - /// version already present — so a stub built here would silently satisfy a later restore - /// anywhere on the machine. On its own --packages also hides the targeting packs the - /// project needs (NU1101 Microsoft.NETCore.App.Ref), so the real folder is supplied as a - /// fallback: lookups find it there, installs still go to the throwaway folder. A fallback folder - /// that does not exist is a hard NU1301, hence the create. - /// See https://learn.microsoft.com/nuget/consume-packages/managing-the-global-packages-and-cache-folders. - /// - /// - public static async Task<(int ExitCode, string Output)> RestoreAsync(string projectPath, string feedPath) - { - using var packagesDirectory = new TempDirectory(); - - var startInfo = new ProcessStartInfo("dotnet") - { - RedirectStandardOutput = true, - RedirectStandardError = true, - WorkingDirectory = Path.GetDirectoryName(projectPath)! - }; - - startInfo.Environment["NUGET_FALLBACK_PACKAGES"] = EnsureGlobalPackagesFolder(); - - startInfo.ArgumentList.Add("restore"); - startInfo.ArgumentList.Add(projectPath); - startInfo.ArgumentList.Add("--source"); - startInfo.ArgumentList.Add(feedPath); - startInfo.ArgumentList.Add("--packages"); - startInfo.ArgumentList.Add(packagesDirectory.Path); - - using var process = Process.Start(startInfo)!; - // Read both streams concurrently to avoid deadlock when a pipe buffer fills. - var stdoutTask = process.StandardOutput.ReadToEndAsync(); - var stderrTask = process.StandardError.ReadToEndAsync(); - await process.WaitForExitAsync(); - - return (process.ExitCode, await stdoutTask + await stderrTask); - } - - /// - /// The real global packages folder, used as a fallback so targeting packs still resolve. - /// - /// - /// NUGET_PACKAGES wins when it is set, which is how CI relocates the folder; otherwise - /// NuGet's default is ~/.nuget/packages on every platform. The directory is created when - /// absent because NuGet fails a restore outright (NU1301) on a fallback folder that does - /// not exist. - /// - private static string EnsureGlobalPackagesFolder() - { - var folder = Environment.GetEnvironmentVariable("NUGET_PACKAGES") is { Length: > 0 } configured - ? configured - : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages"); - - Directory.CreateDirectory(folder); - return folder; - } - - /// - /// A directory that is deleted when the restore that used it is done. - /// - private sealed class TempDirectory : IDisposable - { - private readonly DirectoryInfo _directory = Directory.CreateTempSubdirectory("aspire-offline-feed"); - - public string Path => _directory.FullName; - - public void Dispose() - { - try - { - _directory.Delete(recursive: true); - } - catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) - { - // A leftover throwaway folder is harmless; failing the test over it is not. - } - } - } -} diff --git a/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs b/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs index 53d7fe03307..422f49f670a 100644 --- a/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs +++ b/tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs @@ -22,8 +22,7 @@ public static CliExecutionContext CreateExecutionContext( string? logFilePath = null, string? identityVersion = null, string? identityCommit = null, - bool identityOverridden = false, - bool identityVersionForged = false) + bool identityOverridden = false) { return CreateExecutionContext( workspace.WorkspaceRoot, @@ -31,8 +30,7 @@ public static CliExecutionContext CreateExecutionContext( logFilePath: logFilePath, identityVersion: identityVersion, identityCommit: identityCommit, - identityOverridden: identityOverridden, - identityVersionForged: identityVersionForged); + identityOverridden: identityOverridden); } /// @@ -51,8 +49,7 @@ public static CliExecutionContext CreateExecutionContext( string? identityVersion = null, string? identityCommit = null, bool identityOverridden = false, - DirectoryInfo? identityPackagesDirectory = null, - bool identityVersionForged = false) + DirectoryInfo? identityPackagesDirectory = null) { var root = rootDirectory.FullName; hivesDirectory ??= new DirectoryInfo(Path.Combine(root, ".aspire", "hives")); @@ -75,7 +72,6 @@ public static CliExecutionContext CreateExecutionContext( nugetServiceIndexOverride: null, identityOverridden: identityOverridden, identityPackagesDirectory: identityPackagesDirectory, - identityVersionForged: identityVersionForged, debugMode: debugMode, homeDirectory: homeDirectory, packagesDirectory: packagesDirectory); diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj index 464206d0208..6dfc6bf2fd3 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj @@ -22,12 +22,6 @@ - - - - - diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index a40cc8e2782..25c685c198e 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -4,7 +4,6 @@ #pragma warning disable ASPIREBROWSERLOGS001 // Type is for evaluation purposes only using System.Reflection; -using System.Text.RegularExpressions; using Aspire.Hosting.Azure; using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.RemoteHost; @@ -15,7 +14,7 @@ namespace Aspire.Hosting.CodeGeneration.TypeScript.Tests; -public partial class AtsTypeScriptCodeGeneratorTests +public class AtsTypeScriptCodeGeneratorTests { private readonly AtsTypeScriptCodeGenerator _generator = new(); @@ -777,7 +776,8 @@ public void AspireUnion_InterfaceHandleInput_GeneratesExpandedUnion() [Fact] public void MapInputUnionTypeToTypeScript_ThrowsOnEmptyUnion() { - var projector = new TypeScriptApiProjector(CreateContextFromTestAssembly()); + var method = typeof(AtsTypeScriptCodeGenerator).GetMethod("MapInputUnionTypeToTypeScript", BindingFlags.Instance | BindingFlags.NonPublic); + Assert.NotNull(method); var typeRef = new AtsTypeRef { @@ -786,8 +786,9 @@ public void MapInputUnionTypeToTypeScript_ThrowsOnEmptyUnion() UnionTypes = [], }; - var ex = Assert.Throws(() => projector.MapInputUnionTypeToTypeScript(typeRef)); - Assert.Equal("Union input types must define at least one member type.", ex.Message); + var ex = Assert.Throws(() => method.Invoke(_generator, [typeRef])); + Assert.IsType(ex.InnerException); + Assert.Equal("Union input types must define at least one member type.", ex.InnerException.Message); } [Fact] @@ -1128,29 +1129,15 @@ private static AtsContext CreateContextFromTestAssembly() private static AtsContext WithAdditionalCapabilities(AtsContext context, params AtsCapabilityInfo[] capabilities) { - var result = new AtsContext + return new AtsContext { Capabilities = [.. context.Capabilities, .. capabilities], HandleTypes = context.HandleTypes, DtoTypes = context.DtoTypes, EnumTypes = context.EnumTypes, ExportedValues = context.ExportedValues, - Diagnostics = context.Diagnostics, - CapabilityExportingAssemblyNames = context.CapabilityExportingAssemblyNames - .Concat(capabilities.Select(capability => - new KeyValuePair(capability.CapabilityId, TestPackageName))) - .ToDictionary(static pair => pair.Key, static pair => pair.Value, StringComparer.Ordinal) + Diagnostics = context.Diagnostics }; - - foreach (var (id, method) in context.Methods) - { - result.Methods[id] = method; - } - foreach (var (id, property) in context.Properties) - { - result.Properties[id] = property; - } - return result; } private static AtsCapabilityInfo CreateDistributedApplicationBuilderCapability( @@ -1816,12 +1803,9 @@ public async Task Generate_SameMethodNameOnDifferentTypes_MergesOptionsInterface // only included parameters from whichever overload was registered first. var code = GenerateTwoPassCode(); - // Extract just the merged options interface for snapshot verification. The fixture's - // withDataVolume overloads are owned by the test assembly, so they merge into that - // assembly's interface rather than into the core one of the same base name. - var interfaceName = $"{TestOptionsPrefix}$WithDataVolumeOptions"; - var interfaceStart = code.IndexOf($"export interface {interfaceName}", StringComparison.Ordinal); - Assert.True(interfaceStart >= 0, $"{interfaceName} interface not found in generated code"); + // Extract just the WithDataVolumeOptions interface for snapshot verification. + var interfaceStart = code.IndexOf("export interface WithDataVolumeOptions", StringComparison.Ordinal); + Assert.True(interfaceStart >= 0, "WithDataVolumeOptions interface not found in generated code"); var interfaceEnd = code.IndexOf("}", interfaceStart, StringComparison.Ordinal); var interfaceBody = code[interfaceStart..(interfaceEnd + 1)]; @@ -1901,68 +1885,18 @@ public void Scanner_PackageManagerMethods_ExpandToAllJavaScriptResourceTypes(str Assert.Contains(expandedTypeIds, id => id.Contains(nameof(JavaScript.ViteAppResource), StringComparison.Ordinal)); } - // ===== Canonical API export ===== - // - // The canonical export is the contract aspire.dev consumes to render TypeScript API - // documentation. It must be produced from the same resolved projection the source - // emitter uses, because documentation that reconstructs signatures from raw ATS - // drifts from the SDK that actually ships (microsoft/aspire#17608). - - /// - /// The exporting package for the canonical export tests. The test assembly owns the - /// documented symbols; Aspire.Hosting contributes referenced types through the closure. - /// - private const string TestPackageName = "Aspire.Hosting.CodeGeneration.TypeScript.Tests"; - private const string TestPackageVersion = "13.5.0"; - - /// - /// The qualifier the projector derives from for options - /// interfaces it owns. - /// - /// - /// Options interfaces are named after the assembly that exports the capability, so that a - /// package's export names an interface the same way whether it was projected on its own or - /// alongside every other package. Only Aspire.Hosting keeps unqualified names, so the - /// fixture's own interfaces carry this prefix. - /// - private const string TestOptionsPrefix = "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests"; + private const string ApiExportPackageName = "Aspire.Hosting.CodeGeneration.TypeScript.Tests"; + private const string ApiExportPackageVersion = "13.5.0"; [Fact] - public async Task ApiExportUsesTheSameResolvedSignaturesAsGeneratedSource() + public async Task ApiExportWriterProducesFocusedCanonicalJson() { - var atsContext = CreateOwnershipFilteredContext(); - - var projector = new TypeScriptApiProjector(atsContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - - var exportJson = TypeScriptApiExportWriter.WriteToJson(model, indented: true); - - await Verify(exportJson, extension: "json") - .UseFileName("AtsTypeScriptCodeGeneratorTests.ApiExport"); - - // Declaration fragments are snapshotted separately: aspire.dev concatenates them in - // stable-ID order and type-checks the result, so their exact text is a contract. - var declarations = string.Join( - "\n\n", - model.Declarations.Select(declaration => $"// {declaration.Id}\n{declaration.Content}")); - - await Verify(declarations, extension: "txt") - .UseFileName("AtsTypeScriptCodeGeneratorTests.ApiDeclarations"); - } - - [Fact] - public void ApiExportWritesPlainObsoleteMembersAsDeprecated() - { - var obsoleteAttribute = typeof(PlainObsoleteFixture).GetMethod(nameof(PlainObsoleteFixture.Old))! - .GetCustomAttribute()!; - var model = new TypeScriptApiModel { SchemaVersion = 1, Language = "typescript", - Package = new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), + Generator = new TypeScriptApiGeneratorIdentity("Aspire.Hosting.CodeGeneration.TypeScript", "13.5.0"), + Package = new TypeScriptApiPackageIdentity("Aspire.Hosting.Contoso", "1.2.3"), Modules = [ new TypeScriptApiModule @@ -1972,1163 +1906,231 @@ public void ApiExportWritesPlainObsoleteMembersAsDeprecated() [ new TypeScriptApiItem { - Id = "type:Test", - TypeId = "Test", + Id = "interface:ContosoResource", + TypeId = "Aspire.Hosting.Contoso/ContosoResource", Kind = TypeScriptApiItemKind.Interface, - Name = "Test", - Declaration = "export interface Test", - OwningAssemblyName = TestPackageName, + Name = "ContosoResource", + Declaration = "export interface ContosoResource", + OwningAssemblyName = "Aspire.Hosting.Contoso", + Summary = "A Contoso resource.", Members = [ new TypeScriptApiMember { - Id = "member:Test.old", + Id = "member:ContosoResource.configure", Kind = TypeScriptApiItemKind.Method, - Name = "old", - Declaration = "old(): void", - DeprecationMessage = obsoleteAttribute.Message ?? string.Empty + Name = "configure", + Declaration = "configure(enabled?: boolean): Promise", + CapabilityId = "Aspire.Hosting.Contoso/configure", + OwningAssemblyName = "Aspire.Hosting.Contoso", + Parameters = + [ + new TypeScriptApiParameter + { + Name = "enabled", + DeclaredType = "boolean", + IsOptional = true, + Summary = "Whether configuration is enabled." + } + ], + ReturnType = "Promise" } ] } ] } ], - Declarations = [] - }; - - var exportJson = TypeScriptApiExportWriter.WriteToJson(model, indented: false); - using var document = System.Text.Json.JsonDocument.Parse(exportJson); - var member = document.RootElement.GetProperty("modules")[0].GetProperty("items")[0].GetProperty("members")[0]; - - Assert.True(member.TryGetProperty("deprecated", out var deprecated)); - Assert.Equal(string.Empty, deprecated.GetString()); - } - - [Fact] - public void ApiExportMethodParametersMatchResolvedPublicSignatures() - { - var atsContext = CreateOwnershipFilteredContext(); - var template = atsContext.Capabilities.Single(c => - c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync"); - var stringParameter = atsContext.Capabilities - .Single(c => c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging") - .Parameters.Single(p => p.Name == "logLevel"); - var boolParameter = atsContext.Capabilities - .Single(c => c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString") - .Parameters.Single(p => p.Name == "enabled"); - var dtoParameter = atsContext.Capabilities - .Single(c => c.CapabilityId == "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig") - .Parameters.Single(p => p.Name == "config"); - var cancellationTokenParameter = template.Parameters.Single(p => p.Name == "cancellationToken"); - - AtsCapabilityInfo CreateCapability(string methodName, params AtsParameterInfo[] parameters) - => new() - { - CapabilityId = $"{TestPackageName}/{methodName}", - MethodName = methodName, - Parameters = parameters, - ReturnType = template.ReturnType, - TargetTypeId = template.TargetTypeId, - TargetType = template.TargetType, - TargetParameterName = template.TargetParameterName, - ExpandedTargetTypes = template.ExpandedTargetTypes, - ReturnsBuilder = template.ReturnsBuilder, - CapabilityKind = template.CapabilityKind - }; - - var contextWithEdgeCases = WithAdditionalCapabilities( - atsContext, - CreateCapability( - "withOptionsCollision", - new AtsParameterInfo - { - Name = "options", - Type = stringParameter.Type, - Documentation = new AtsDocumentationInfo { Summary = "Required options value." } - }, - new AtsParameterInfo - { - Name = "optionsBag", - Type = stringParameter.Type, - Documentation = new AtsDocumentationInfo { Summary = "Required options bag value." } - }, - new AtsParameterInfo - { - Name = "enabled", - Type = boolParameter.Type, - IsOptional = true, - Documentation = new AtsDocumentationInfo { Summary = "Whether the behavior is enabled." } - }), - CreateCapability( - "withOptionalOptionsField", - new AtsParameterInfo - { - Name = "options", - Type = stringParameter.Type, - IsOptional = true, - Documentation = new AtsDocumentationInfo { Summary = "An optional value stored in the generated options bag." } - }, - new AtsParameterInfo - { - Name = "enabled", - Type = boolParameter.Type, - IsOptional = true, - Documentation = new AtsDocumentationInfo { Summary = "Whether the behavior is enabled." } - }), - CreateCapability( - "withDirectOptionsAndCancellation", - new AtsParameterInfo - { - Name = "options", - Type = dtoParameter.Type, - IsOptional = true, - Documentation = new AtsDocumentationInfo { Summary = "Direct options." } - }, - new AtsParameterInfo - { - Name = "cancellationToken", - Type = cancellationTokenParameter.Type, - IsOptional = true, - Documentation = new AtsDocumentationInfo { Summary = "Cancellation token." } - })); - - var projector = new TypeScriptApiProjector(contextWithEdgeCases); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - var testRedisResource = Assert.Single( - model.Modules.SelectMany(module => module.Items), - item => item.Name == nameof(TestRedisResource)); - - var withOptionalString = Assert.Single( - testRedisResource.Members, - member => member.Name == "withOptionalString"); - Assert.Collection( - withOptionalString.Parameters, - parameter => AssertParameter(parameter, "options", "WithOptionalStringOptions", isOptional: true)); - - var withOptionsCollision = Assert.Single( - testRedisResource.Members, - member => member.Name == "withOptionsCollision"); - Assert.Equal( - "withOptionsCollision(options: string, optionsBag: string, _optionsBag?: WithOptionsCollisionOptions): Promise", - withOptionsCollision.Declaration); - Assert.Collection( - withOptionsCollision.Parameters, - parameter => AssertParameter(parameter, "options", "string", isOptional: false, "Required options value."), - parameter => AssertParameter(parameter, "optionsBag", "string", isOptional: false, "Required options bag value."), - parameter => AssertParameter(parameter, "_optionsBag", "WithOptionsCollisionOptions", isOptional: true)); - - var withOptionalOptionsField = Assert.Single( - testRedisResource.Members, - member => member.Name == "withOptionalOptionsField"); - Assert.Equal( - "withOptionalOptionsField(options?: WithOptionalOptionsFieldOptions): Promise", - withOptionalOptionsField.Declaration); - Assert.Collection( - withOptionalOptionsField.Parameters, - parameter => AssertParameter(parameter, "options", "WithOptionalOptionsFieldOptions", isOptional: true)); - - var withDirectOptionsAndCancellation = Assert.Single( - testRedisResource.Members, - member => member.Name == "withDirectOptionsAndCancellation"); - Assert.Equal( - "withDirectOptionsAndCancellation(options?: TestConfigDto, cancellationToken?: AbortSignal | CancellationToken): Promise", - withDirectOptionsAndCancellation.Declaration); - Assert.Collection( - withDirectOptionsAndCancellation.Parameters, - parameter => AssertParameter(parameter, "options", "TestConfigDto", isOptional: true, "Direct options."), - parameter => AssertParameter(parameter, "cancellationToken", "AbortSignal | CancellationToken", isOptional: true, "Cancellation token.")); - - var generatedSource = new AtsTypeScriptCodeGenerator() - .GenerateDistributedApplication(contextWithEdgeCases)["aspire.mts"]; - var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); - var testRedisResourceMembers = generatedInterfaceMembers[nameof(TestRedisResource)]; - - Assert.Contains(withOptionsCollision.Declaration, testRedisResourceMembers); - Assert.Contains(withOptionalOptionsField.Declaration, testRedisResourceMembers); - Assert.Contains(withDirectOptionsAndCancellation.Declaration, testRedisResourceMembers); - Assert.Contains( - "async withOptionalOptionsField(optionsBag?: WithOptionalOptionsFieldOptions): Promise {", - generatedSource); - Assert.Contains("const options = optionsBag?.options;", generatedSource); - Assert.DoesNotContain("const options = options?.options;", generatedSource); - - static void AssertParameter( - TypeScriptApiParameter parameter, - string name, - string declaredType, - bool isOptional, - string? summary = null) - { - Assert.Equal(name, parameter.Name); - Assert.Equal(declaredType, parameter.DeclaredType); - Assert.Equal(isOptional, parameter.IsOptional); - Assert.Equal(summary, parameter.Summary); - } - } - - /// - /// The export contract promises that concatenating a manifest's declaration fragments type-checks - /// without site-authored shims, so every symbol a fragment names must be declared by some fragment. - /// This caught a real gap: handle types with no wrapper class surface in signatures under their raw - /// XHandle alias, but the fragment pass derived a different name and declared nothing. - /// - [Fact] - public void ApiExportDeclarationFragmentsReferenceOnlyDeclaredOrBuiltInSymbols() - { - var atsContext = CreateOwnershipFilteredContext(); - - var projector = new TypeScriptApiProjector(atsContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - - AssertDeclarationFragmentsAreSelfContained(model); - } - - /// - /// A package contributing an entry point must be self-contained too. - /// - /// - /// Entry points are the one exported shape that names AspireClientRpc: they are free - /// functions, so the client is passed explicitly as the first parameter. The runtime fragment - /// declared every other base-library symbol but not that one, so an Aspire.Hosting export - /// published a signature naming a type no fragment declared, and aspire.dev's concatenation of - /// the manifest failed to resolve it. The context used above has no entry point, which is why - /// the sibling test never saw the gap. - /// - [Fact] - public void ApiExportDeclarationFragmentsForEntryPointsReferenceOnlyDeclaredOrBuiltInSymbols() - { - var context = CreateEntryPointContext(); - - var projector = new TypeScriptApiProjector(context); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(EntryPointPackage, TestPackageVersion), - [EntryPointPackage]); - - AssertDeclarationFragmentsAreSelfContained(model); - } - - private static void AssertDeclarationFragmentsAreSelfContained(TypeScriptApiModel model) - { - var declaredNames = new HashSet(StringComparer.Ordinal); - - foreach (var declaration in model.Declarations) - { - foreach (Match match in DeclaredNameRegex().Matches(declaration.Content)) - { - declaredNames.Add(match.Groups[1].Value); - } - } - - var referenced = new HashSet(StringComparer.Ordinal); - - foreach (var declaration in model.Declarations) - { - foreach (var name in ExtractReferencedTypeNames(declaration.Content)) - { - referenced.Add(name); - } - } - - // Rendered item and member signatures are scanned too: they name the same symbols the - // fragments must supply, and they are where an alias the fragments never declared shows up. - // Enum items are excluded: their members are value names declared by the enum itself, not - // references to other symbols. - foreach (var item in model.Modules - .SelectMany(module => module.Items) - .Where(item => item.Kind != TypeScriptApiItemKind.Enum)) - { - var signatures = item.Members - .Select(member => member.Declaration) - .Append(item.Declaration) - .Concat(item.Extends); - - foreach (var name in signatures.SelectMany(ExtractReferencedTypeNames)) - { - referenced.Add(name); - } - } - - referenced.ExceptWith(declaredNames); - referenced.ExceptWith(s_typeScriptBuiltInNames); - - Assert.True( - referenced.Count == 0, - $"Declaration fragments reference undeclared symbols: {string.Join(", ", referenced.OrderBy(name => name, StringComparer.Ordinal))}"); - } - - /// - /// TypeScript symbols the language itself provides, so fragments may reference them without - /// declaring them. - /// - private static readonly HashSet s_typeScriptBuiltInNames = new(StringComparer.Ordinal) - { - "Promise", "PromiseLike", "Record", "Partial", "Readonly", "Array", "Function", "Date", "Error" - }; - - /// - /// Collects the type names a declaration fragment references. Enum bodies are dropped first because - /// their members are declared by the enum itself, then string literals are removed so that handle - /// aliases such as export type XHandle = Handle<'Assembly/Namespace.Type'>; do not look - /// like type references. - /// - private static IEnumerable ExtractReferencedTypeNames(string content) - { - var withoutEnums = EnumDeclarationRegex().Replace(content, string.Empty); - var withoutLiterals = StringLiteralRegex().Replace(withoutEnums, "\"\""); - - foreach (Match match in IdentifierRegex().Matches(withoutLiterals)) - { - var name = match.Value; - - // Conventional generic parameter names (T, TKey, TValue) are introduced by the - // declaration that uses them, so they are never resolved against other fragments. - if (name is "T" || (name.Length > 1 && name[0] == 'T' && char.IsUpper(name[1]))) - { - continue; - } - - yield return name; - } - } - - [GeneratedRegex(@"^export (?:interface|enum|type) ([\w$]+)", RegexOptions.Multiline)] - private static partial Regex DeclaredNameRegex(); - - [GeneratedRegex(@"enum \w+ \{[^}]*\}")] - private static partial Regex EnumDeclarationRegex(); - - [GeneratedRegex(@"'[^']*'|""[^""]*""")] - private static partial Regex StringLiteralRegex(); - - // '$' is part of an identifier, not a boundary: package-qualified options interfaces use it as - // the qualifier terminator, so \b would split one symbol into two undeclared halves. - [GeneratedRegex(@"(? m.Kind == TypeScriptApiItemKind.Method)) + Declarations = + [ + new TypeScriptApiDeclaration { - Assert.True( - generatedInterfaceMembers.TryGetValue(item.Name, out var members), - $"Exported type '{item.Name}' has no generated public interface."); - - Assert.True( - members.Contains(member.Declaration), - $"Exported declaration '{member.Declaration}' on '{item.Name}' does not appear in the generated public interface. " + - $"Generated members: {string.Join(", ", members)}"); - - checkedDeclarations++; + Id = "interface:ContosoResource", + Content = "export interface ContosoResource {\r\n configure(enabled?: boolean): Promise;\r\n}", + OwningAssemblyName = "Aspire.Hosting.Contoso" } - } - } - - Assert.True(checkedDeclarations > 0, "The canonical export produced no method declarations to compare."); - } - - [Fact] - public void ApiExportUsesPromiseWrappersFromReferencedHandleCapabilities() - { - var fullContext = CreateReferencedHandleContext(); - var exportContext = AtsContextFilter.FilterForApiExport( - fullContext, - [TestPackageName]); - - var projector = new TypeScriptApiProjector(exportContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - - var ownedContext = Assert.Single( - model.Modules.SelectMany(module => module.Items), - item => item.Name == "OwnedContext"); - var exportedMethod = Assert.Single( - ownedContext.Members, - member => member.Name == "getForeign"); - - var generatedSource = new AtsTypeScriptCodeGenerator() - .GenerateDistributedApplication(fullContext)["aspire.mts"]; - var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); - - Assert.Contains(exportedMethod.Declaration, generatedInterfaceMembers["OwnedContext"]); - } - - [Fact] - public void ApiExportUsesResourceWrappersReferencedOnlyBySupportingCapabilities() - { - var fullContext = CreateReferencedHandleContext(); - var exportContext = AtsContextFilter.FilterForApiExport( - fullContext, - [TestPackageName]); - - var projector = new TypeScriptApiProjector(exportContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - - var ownedContext = Assert.Single( - model.Modules.SelectMany(module => module.Items), - item => item.Name == "OwnedContext"); - var exportedMethod = Assert.Single( - ownedContext.Members, - member => member.Name == "waitFor"); + ] + }; - var generatedSource = new AtsTypeScriptCodeGenerator() - .GenerateDistributedApplication(fullContext)["aspire.mts"]; - var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); + var json = TypeScriptApiExportWriter.WriteToJson(model, indented: true); - Assert.Contains(exportedMethod.Declaration, generatedInterfaceMembers["OwnedContext"]); + await Verify(json, extension: "json") + .UseFileName("AtsTypeScriptCodeGeneratorTests.FocusedApiExport"); } [Fact] - public void ApiExportRetainsExpandedTargetsFromSupportingCapabilities() + public void ApiExportIncludesCodeGeneratorIdentity() { - var fullContext = CreateReferencedHandleContext(); - var exportContext = AtsContextFilter.FilterForApiExport( - fullContext, - [TestPackageName]); - - var projector = new TypeScriptApiProjector(exportContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - - var ownedContext = Assert.Single( - model.Modules.SelectMany(module => module.Items), - item => item.Name == "OwnedContext"); - var exportedMethod = Assert.Single( - ownedContext.Members, - member => member.Name == "waitForForeign"); + var model = ProjectApi(CreateEntryPointContext(ApiExportPackageName), ApiExportPackageName); + using var document = System.Text.Json.JsonDocument.Parse(TypeScriptApiExportWriter.WriteToJson(model)); + var generator = document.RootElement.GetProperty("generator"); + var assembly = typeof(AtsTypeScriptCodeGenerator).Assembly; - var generatedSource = new AtsTypeScriptCodeGenerator() - .GenerateDistributedApplication(fullContext)["aspire.mts"]; - var generatedInterfaceMembers = ParsePublicInterfaceMembers(generatedSource); - - Assert.Contains(exportedMethod.Declaration, generatedInterfaceMembers["OwnedContext"]); + Assert.Equal(assembly.GetName().Name, generator.GetProperty("name").GetString()); Assert.Equal( - exportContext.Capabilities.Count, - exportContext.Capabilities.Select(capability => capability.CapabilityId).Distinct(StringComparer.Ordinal).Count()); - } - - [Fact] - public void ApiExportRetainsAssemblyOwnedMembersOnExternalTypes() - { - var fullContext = CreateContextFromBothAssemblies(); - var exportContext = AtsContextFilter.FilterForApiExport( - fullContext, - ["Aspire.Hosting"]); - - var projector = new TypeScriptApiProjector(exportContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity("Aspire.Hosting", TestPackageVersion), - ["Aspire.Hosting"]); - var items = model.Modules.SelectMany(module => module.Items).ToList(); - - var configurationSection = Assert.Single(items, item => item.Name == "ConfigurationSection"); - Assert.Contains(configurationSection.Members, member => member.Name == "key"); - Assert.Contains(configurationSection.Members, member => member.Name == "path"); - Assert.Contains(configurationSection.Members, member => member.Name == "value"); - - var hostEnvironment = Assert.Single(items, item => item.Name == "HostEnvironment"); - Assert.Contains(hostEnvironment.Members, member => member.Name == "applicationName"); - Assert.Contains(hostEnvironment.Members, member => member.Name == "environmentName"); - Assert.Contains(hostEnvironment.Members, member => member.Name == "contentRootPath"); - } - - /// - /// DTO interfaces carry properties that have no C# counterpart, such as the client-only - /// throwOnPendingRejections on CreateBuilderOptions. Those used to be appended by the - /// module emitter alone, so the exported interface described fewer properties than the module we - /// ship and aspire.dev documented a DTO nobody could actually pass. - /// - [Fact] - public void ApiExportDtoPropertiesMatchTheGeneratedDtoInterfaces() - { - var atsContext = CreateOwnershipFilteredContext(); - - var projector = new TypeScriptApiProjector(atsContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - - var generatedSource = new AtsTypeScriptCodeGenerator() - .GenerateDistributedApplication(atsContext)["aspire.mts"]; - - var checkedDtos = 0; - foreach (var item in model.Modules.SelectMany(module => module.Items).Where(item => item.Kind == TypeScriptApiItemKind.Dto)) - { - var body = ExtractExportedInterfaceBody(generatedSource, item.Name); - Assert.NotNull(body); - - var generatedProperties = body! - .Split('\n', StringSplitOptions.RemoveEmptyEntries) - .Select(line => line.Trim()) - .Where(line => line.EndsWith(';') && !line.StartsWith("//", StringComparison.Ordinal) && !line.StartsWith("*", StringComparison.Ordinal) && !line.StartsWith("/*", StringComparison.Ordinal)) - .Select(line => line[..^1]) - .ToList(); - - Assert.Equal(generatedProperties, item.Members.Select(member => member.Declaration).ToList()); - checkedDtos++; - } - - Assert.True(checkedDtos > 0, "The canonical export produced no DTO items to compare."); - } - - /// - /// Returns the body of export interface {name} { ... } from generated module source, or - /// when the generated source declares no such interface. - /// - private static string? ExtractExportedInterfaceBody(string generatedSource, string interfaceName) - { - var header = $"export interface {interfaceName} {{"; - var start = generatedSource.IndexOf(header, StringComparison.Ordinal); - if (start < 0) - { - return null; - } - - var bodyStart = start + header.Length; - var end = generatedSource.IndexOf("\n}", bodyStart, StringComparison.Ordinal); - return end < 0 ? null : generatedSource[bodyStart..end]; - } - - /// - /// Consumers deduplicate declaration fragments by comparing content for the same ID across packages, - /// so the text has to be byte-identical no matter which OS produced the export. Some fragments come - /// from raw string literals, which pick up CRLF when the repository is checked out on Windows. - /// - [Fact] - public void ApiExportDeclarationContentUsesPlatformIndependentLineEndings() - { - var atsContext = CreateOwnershipFilteredContext(); - - var projector = new TypeScriptApiProjector(atsContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); - - Assert.All(model.Declarations, declaration => - Assert.DoesNotContain('\r', declaration.Content)); + assembly.GetCustomAttribute()!.InformationalVersion, + generator.GetProperty("version").GetString()); } [Fact] - public void ApiExportSeparatesReferencedTypesFromPackageOwnedItems() + public void ApiReferenceExporterRequiresAndHonorsCancellation() { - var atsContext = CreateOwnershipFilteredContext(); - - var projector = new TypeScriptApiProjector(atsContext); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(TestPackageName, TestPackageVersion), - [TestPackageName]); + var method = typeof(IApiReferenceExporter).GetMethod(nameof(IApiReferenceExporter.ExportApi)); - var documentedItems = model.Modules.SelectMany(module => module.Items).ToList(); - - // Every documented item must be something this package published: either it owns the type, - // or it contributes members to a type another package owns. Anything else would republish - // another package's surface under this package's version. - Assert.All(documentedItems, item => - Assert.True( - item.TypeId.StartsWith($"{TestPackageName}/", StringComparison.Ordinal) || - item.OwningAssemblyName == TestPackageName || - item.Kind == TypeScriptApiItemKind.Augmentation, - $"Item '{item.Id}' ({item.TypeId}) is neither package-owned nor a package contribution.")); - - // A package that extends another package's type must not publish a second page for it. The - // owning package's export uses "interface:{name}" for that type, so an augmentation reusing - // that ID would collide across a manifest and claim ownership it does not have. The - // contributing package is part of the ID as well, because every integration that extends - // DistributedApplicationBuilder augments the same interface name. - Assert.All( - documentedItems.Where(item => item.Kind == TypeScriptApiItemKind.Augmentation), - item => + Assert.NotNull(method); + Assert.Collection( + method.GetParameters(), + parameter => Assert.Equal(typeof(AtsContext), parameter.ParameterType), + parameter => Assert.Equal(typeof(ApiReferenceExportOptions), parameter.ParameterType), + parameter => { - Assert.StartsWith($"augmentation:{TestPackageName}:", item.Id, StringComparison.Ordinal); - Assert.NotEqual(TestPackageName, item.OwningAssemblyName); + Assert.Equal(typeof(CancellationToken), parameter.ParameterType); + Assert.False(parameter.HasDefaultValue); }); - // Item IDs are what aspire.dev deduplicates a manifest on, so a repeat would silently drop a page. - var itemIds = documentedItems.Select(item => item.Id).ToList(); - Assert.Equal(itemIds.Count, itemIds.Distinct(StringComparer.Ordinal).Count()); - - // Members are owned per capability, so no documented member may come from another assembly. - Assert.All( - documentedItems.SelectMany(item => item.Members), - member => Assert.Equal(TestPackageName, member.OwningAssemblyName)); - - // The closure must reach types this package does not own; otherwise the fixture would not - // exercise cross-package references at all. - var referencedTypeIds = atsContext.HandleTypes - .Select(type => type.AtsTypeId) - .Where(typeId => !typeId.StartsWith($"{TestPackageName}/", StringComparison.Ordinal)) - .ToList(); - - Assert.NotEmpty(referencedTypeIds); - - var declarationIds = model.Declarations.Select(declaration => declaration.Id).ToList(); - Assert.Equal(declarationIds.Count, declarationIds.Distinct(StringComparer.Ordinal).Count()); - - // Referenced types must reach the declaration fragments under their real owner, otherwise - // the concatenated declarations would not type-check. - Assert.Contains(model.Declarations, declaration => declaration.OwningAssemblyName == "Aspire.Hosting"); - - // Every type name the declarations reference must also be declared by the declarations. - var declaredNames = model.Declarations - .SelectMany(declaration => Regex.Matches(declaration.Content, @"export (?:interface|enum|type) (\w+)")) - .Select(match => match.Groups[1].Value) - .ToHashSet(StringComparer.Ordinal); - - Assert.Contains("ResourceBuilderBase", declaredNames); - Assert.Contains("ContainerResource", declaredNames); - } - - /// - /// Two packages that expose the same capability name with incompatible parameter types must - /// name their options interfaces the same way whether they are scanned together or apart. - /// - /// - /// sdk export runs one app host per package, so the projector only ever sees the - /// requested package plus core, while sdk generate sees whatever the user's app host - /// references. Deriving the name from the exporting assembly is what makes those two views - /// agree: naming by method alone gave both packages RunAsEmulatorOptions when projected - /// apart, which is a duplicate declaration with conflicting members once aspire.dev - /// concatenates their fragments. - /// - [Fact] - public void OptionsInterfaceNamesDoNotDependOnWhichOtherPackagesWereScanned() - { - var scannedTogether = new TypeScriptApiProjector(CreateEmulatorCollisionContext()); - var hubsAlone = new TypeScriptApiProjector(CreateEmulatorCollisionContext(includeServiceBus: false)); - var busAlone = new TypeScriptApiProjector(CreateEmulatorCollisionContext(includeEventHubs: false)); - - static string EmulatorInterfaceName(TypeScriptApiProjector projector, string packageName) - => projector.ResolveOptionsInterfaceName( - projector.Resolved.Context.Capabilities.Single(c => c.CapabilityId == $"{packageName}/runAsEmulator")); + using var cancellation = new CancellationTokenSource(); + cancellation.Cancel(); - Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions", EmulatorInterfaceName(hubsAlone, CollisionPackageA)); - Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions", EmulatorInterfaceName(busAlone, CollisionPackageB)); - - Assert.Equal( - EmulatorInterfaceName(hubsAlone, CollisionPackageA), - EmulatorInterfaceName(scannedTogether, CollisionPackageA)); - Assert.Equal( - EmulatorInterfaceName(busAlone, CollisionPackageB), - EmulatorInterfaceName(scannedTogether, CollisionPackageB)); + IApiReferenceExporter exporter = new AtsTypeScriptApiReferenceExporter(); + Assert.Throws(() => exporter.ExportApi( + CreateEntryPointContext(ApiExportPackageName), + new ApiReferenceExportOptions( + ApiExportPackageName, + ApiExportPackageVersion, + [ApiExportPackageName]), + cancellation.Token)); } - /// - /// An entry point's exported declaration describes the function the generator actually emits. - /// - /// - /// Entry points are free functions, so the generator emits them taking the client explicitly and - /// keeping optional arguments positional. The exporter used to route them through the member - /// signature resolver instead, which dropped client and folded the optionals into an - /// options bag, so the published declaration described a call that does not exist. Consumers - /// type-check against these declarations, so the disagreement surfaces as a compile error in - /// their code rather than anywhere near this repository. - /// [Fact] - public void ApiExportDeclaresEntryPointsWithTheSignatureTheGeneratorEmits() + public void ApiExportEntrypointIdsIncludeTheOwningAssembly() { - var context = CreateEntryPointContext(); + const string firstPackage = "Aspire.Hosting.Contoso.EntryPoints"; + const string secondPackage = "Aspire.Hosting.Fabrikam.EntryPoints"; - var projector = new TypeScriptApiProjector(context); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(EntryPointPackage, TestPackageVersion), - [EntryPointPackage]); - - var exported = Assert.Single( - model.Modules.SelectMany(module => module.Items), - item => item.Name == "startThing"); + var first = Assert.Single(ProjectApi(CreateEntryPointContext(firstPackage), firstPackage) + .Modules.SelectMany(module => module.Items)); + var second = Assert.Single(ProjectApi(CreateEntryPointContext(secondPackage), secondPackage) + .Modules.SelectMany(module => module.Items)); + Assert.Equal($"entrypoint:{firstPackage}:startThing", first.Id); + Assert.Equal($"entrypoint:{secondPackage}:startThing", second.Id); + Assert.NotEqual(first.Id, second.Id); Assert.Equal( "function startThing(client: AspireClientRpc, name: string, retries?: number): Promise", - exported.Declaration); + first.Declaration); var generatedSource = new AtsTypeScriptCodeGenerator() - .GenerateDistributedApplication(context)["aspire.mts"]; - - Assert.Contains( - $"export async {exported.Declaration} {{", - generatedSource, - StringComparison.Ordinal); + .GenerateDistributedApplication(CreateEntryPointContext(firstPackage))["aspire.mts"]; + Assert.Contains($"export async {first.Declaration} {{", generatedSource, StringComparison.Ordinal); } - /// - /// Two assemblies whose names differ only in where their separators fall must not collapse to - /// the same options-interface qualifier. - /// - /// - /// The qualifier used to keep only letters and digits, so Contoso.Foo.Bar and - /// Contoso.FooBar both produced ContosoFooBar. A per-package export cannot see - /// that some other package would land on the same qualifier, so it has no opportunity to - /// disambiguate the way full generation could; the two packages would each emit a - /// ContosoFooBarRunAsEmulatorOptions with different members and aspire.dev would - /// concatenate them into a duplicate declaration that does not compile. Encoding the separator - /// instead of dropping it makes the qualifier injective, which is what removes the possibility. - /// [Fact] - public void OptionsInterfaceQualifiersDistinguishAssembliesThatDifferOnlyBySeparatorPlacement() + public void ApiExportExplicitInterfaceMemberNameMatchesItsDeclaration() { - var dotted = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.Foo.Bar"); - var joined = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.FooBar"); - - Assert.NotEqual(dotted, joined); - Assert.Equal("Contoso_x002E_Foo_x002E_Bar$RunAsEmulatorOptions", dotted); - Assert.Equal("Contoso_x002E_FooBar$RunAsEmulatorOptions", joined); - } - - /// - /// Two individually injective encodings still alias if they are simply concatenated, so the - /// qualifier has to be terminated. - /// - [Fact] - public void OptionsInterfaceQualifiersDoNotAliasAcrossTheQualifierBoundary() - { - // Contoso + fooBar and ContosoFoo + bar both produce ContosoFooBarOptions without a seam, - // and the collision guard only inspects unqualified names, so nothing would catch it. - Assert.NotEqual( - TypeScriptApiProjector.GetOptionsInterfaceName("fooBar", "Contoso"), - TypeScriptApiProjector.GetOptionsInterfaceName("bar", "ContosoFoo")); - } - - /// - /// Escape sequences are terminated so characters after the escaped code unit cannot become part - /// of the escape itself. - /// - [Fact] - public void OptionsInterfaceQualifiersUseTerminatedEscapes() - { - Assert.NotEqual( - TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.Foo-Bar"), - TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.Foo.x2DBar")); - - Assert.NotEqual( - TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.\u01234"), - TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Contoso.\u1234")); - } - - /// - /// An assembly name that starts with a digit still yields a parseable TypeScript identifier. - /// - /// - /// Assembly names may begin with a digit -- 3rdParty.Aspire is legal -- but TypeScript - /// identifiers may not, so the unguarded qualifier emitted - /// interface 3rdPartyAspireRunAsEmulatorOptions, which is a syntax error rather than a - /// naming inconvenience. The escape cannot alias a name that already begins with an underscore - /// because a literal underscore encodes as a doubled one. - /// - [Fact] - public void OptionsInterfaceQualifiersEscapeAssemblyNamesThatStartWithADigit() - { - var name = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "3rdParty.Aspire"); - - Assert.Equal("_x0033_rdParty_x002E_Aspire$RunAsEmulatorOptions", name); - Assert.True(name[0] is '_' or '$' || char.IsLetter(name[0]), $"'{name}' is not a valid TypeScript identifier."); - Assert.NotEqual(name, TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "_3rdParty.Aspire")); - } - - /// - /// Non-core assemblies are qualified by their complete names, not by a shortened suffix that can - /// overlap other assemblies. - /// - [Fact] - public void OptionsInterfaceQualifiersUseTheFullAssemblyName() - { - var hostingRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Aspire.Hosting.Redis"); - var aspireRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Aspire.Redis"); - var bareRedis = TypeScriptApiProjector.GetOptionsInterfaceName("runAsEmulator", "Redis"); - - Assert.Equal("Aspire_x002E_Hosting_x002E_Redis$RunAsEmulatorOptions", hostingRedis); - Assert.Equal("Aspire_x002E_Redis$RunAsEmulatorOptions", aspireRedis); - Assert.Equal("Redis$RunAsEmulatorOptions", bareRedis); - Assert.Equal(3, new[] { hostingRedis, aspireRedis, bareRedis }.Distinct(StringComparer.Ordinal).Count()); - } - - [Fact] - public void UniqueOptionsInterfaceNamesStayUnqualified() - { - var name = TypeScriptApiProjector.GetOptionsInterfaceName("withUniqueSetting", "Aspire.Hosting.Redis"); - - Assert.Equal("WithUniqueSettingOptions", name); - } - - [Fact] - public void ThirdPartyOptionsInterfaceNamesAreQualifiedEvenWhenTheNameIsUniqueInThisRepository() - { - var name = TypeScriptApiProjector.GetOptionsInterfaceName("withDescription", "Contoso.Aspire.Hosting.Widgets"); - - Assert.Equal("Contoso_x002E_Aspire_x002E_Hosting_x002E_Widgets$WithDescriptionOptions", name); - } - - /// - /// An options interface is documented by, and keyed to, the assembly whose capability produced - /// it rather than the package the export was requested for. - /// - /// - /// The projector's context reaches beyond the requested package, so an unscoped emission would - /// let one package publish its dependencies' options interfaces under its own version. Keying - /// the declaration by the requesting package instead of the owner is the same bug from the - /// other side: the same interface would carry a different fragment id in every export that - /// reached it, so concatenation would redeclare it rather than deduplicate it. - /// - [Fact] - public void ApiExportAttributesOptionsInterfacesToTheAssemblyThatOwnsThem() - { - var projector = new TypeScriptApiProjector(CreateEmulatorCollisionContext()); - var model = projector.BuildApiModel( - new TypeScriptApiPackageIdentity(CollisionPackageA, TestPackageVersion), - [CollisionPackageA]); - - var documentedOptions = model.Modules - .SelectMany(module => module.Items) - .Where(item => item.Kind == TypeScriptApiItemKind.Options) - .ToList(); - - Assert.Collection( - documentedOptions, - item => - { - Assert.Equal("Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions", item.Name); - Assert.Equal(CollisionPackageA, item.OwningAssemblyName); - }); - - var serviceBusDeclaration = Assert.Single( - model.Declarations, - declaration => declaration.Content.Contains("Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions", StringComparison.Ordinal)); - - Assert.Equal($"{CollisionPackageB}:options:Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions", serviceBusDeclaration.Id); - Assert.Equal(CollisionPackageB, serviceBusDeclaration.OwningAssemblyName); - } - - /// - /// A per-package export names a colliding options interface the way full generation names it, - /// on the context the export path actually produces rather than on a raw scan. - /// - /// - /// The determinism test above compares projectors built directly over hand-made contexts, but - /// sdk export never hands the projector a raw scan: - /// narrows it to the requested package first. That difference is the whole bug — naming used to - /// be decided by collision detection over whatever the context happened to hold, so the narrowed - /// view and the full scan reached different answers for the same package. - /// - /// Both directions fail under the old scheme, but at different assertions, and that asymmetry - /// is why the body comparison is here. Event Hubs was scanned first and kept the unsuffixed - /// base name, so it fails only on the name: it produced RunAsEmulatorOptions rather than - /// the Event Hubs assembly-qualified name. Service Bus lost that draw during full generation - /// and was suffixed there while its own single-package export was not, so it disagreed about - /// the interface itself. Checking only that the exported name appears among the generated names - /// would have missed it, because the name did appear -- it just belonged to Event Hubs. The old - /// scheme had Service Bus export RunAsEmulatorOptions as configureContainer?: boolean - /// while the SDK gave that same name to Event Hubs as configureContainer?: string, so a - /// consumer concatenating the export silently got the wrong callback type rather than a - /// redeclaration error. - /// - /// - [Theory] - [InlineData(CollisionPackageA, "Aspire_x002E_Hosting_x002E_Azure_x002E_EventHubs$RunAsEmulatorOptions")] - [InlineData(CollisionPackageB, "Aspire_x002E_Hosting_x002E_Azure_x002E_ServiceBus$RunAsEmulatorOptions")] - public void ApiExportNamesACollidingOptionsInterfaceTheWayGenerationDoes(string packageName, string expectedInterfaceName) - { - var fullContext = CreateEmulatorCollisionContext(); - var exportContext = AtsContextFilter.FilterForApiExport(fullContext, [packageName]); - - var model = new TypeScriptApiProjector(exportContext).BuildApiModel( - new TypeScriptApiPackageIdentity(packageName, TestPackageVersion), - [packageName]); - - var exportedOptions = Assert.Single( - model.Modules.SelectMany(module => module.Items), - item => item.Kind == TypeScriptApiItemKind.Options); - - Assert.Equal(expectedInterfaceName, exportedOptions.Name); - Assert.Equal(packageName, exportedOptions.OwningAssemblyName); - - var generatedSource = new AtsTypeScriptCodeGenerator() - .GenerateDistributedApplication(fullContext)["aspire.mts"]; - - var generatedInterfaces = ParsePublicInterfaceMembers(generatedSource); - Assert.Contains(exportedOptions.Name, generatedInterfaces.Keys); - Assert.Equal( - exportedOptions.Members.Select(member => member.Declaration).OrderBy(d => d, StringComparer.Ordinal), - generatedInterfaces[exportedOptions.Name].OrderBy(d => d, StringComparer.Ordinal)); - } - - private const string CollisionPackageA = "Aspire.Hosting.Azure.EventHubs"; - private const string CollisionPackageB = "Aspire.Hosting.Azure.ServiceBus"; - - /// - /// Builds a manifest where both packages expose runAsEmulator with an optional parameter - /// of the same name but an incompatible type, which is what forced generation to suffix one of - /// the two options interfaces when names were derived from the method alone. - /// - /// - /// The two package names are the real ones: AzureEventHubsExtensions.RunAsEmulator and - /// AzureServiceBusExtensions.RunAsEmulator both take an optional - /// Action<IResourceBuilder<T>> for different T, so their options - /// interfaces cannot be merged. The capabilities here are synthetic; only the shape matters. - /// - private const string EntryPointPackage = "Aspire.Hosting.Contoso.EntryPoints"; - - /// - /// Builds a context holding a single entry-point capability: one with no target type, so it is - /// emitted as a free function rather than as a member of a builder interface. - /// - private static AtsContext CreateEntryPointContext() - { - var capability = new AtsCapabilityInfo + const string targetTypeId = ApiExportPackageName + "/Contoso.WidgetContext"; + var targetType = new AtsTypeRef { - CapabilityId = $"{EntryPointPackage}/startThing", - MethodName = "startThing", - Parameters = + TypeId = targetTypeId, + Category = AtsTypeCategory.Handle + }; + var context = new AtsContext + { + Capabilities = [ - new AtsParameterInfo - { - Name = "name", - Type = new AtsTypeRef { TypeId = AtsConstants.String, Category = AtsTypeCategory.Primitive } - }, - new AtsParameterInfo + new AtsCapabilityInfo { - Name = "retries", - Type = new AtsTypeRef { TypeId = AtsConstants.Number, Category = AtsTypeCategory.Primitive }, - IsOptional = true + CapabilityId = ApiExportPackageName + "/IWidget.configure", + MethodName = "IWidget.configure", + OwningTypeName = "WidgetContext", + Parameters = [], + ReturnType = new AtsTypeRef + { + TypeId = AtsConstants.Void, + Category = AtsTypeCategory.Primitive + }, + TargetTypeId = targetTypeId, + TargetType = targetType, + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.InstanceMethod } ], - ReturnType = new AtsTypeRef { TypeId = AtsConstants.Void, Category = AtsTypeCategory.Primitive }, - ExpandedTargetTypes = [], - CapabilityKind = AtsCapabilityKind.Method - }; - - return new AtsContext - { - Capabilities = [capability], HandleTypes = [], DtoTypes = [], EnumTypes = [], ExportedValues = [], - Diagnostics = [], - CapabilityExportingAssemblyNames = new Dictionary(StringComparer.Ordinal) - { - [capability.CapabilityId] = EntryPointPackage - } + Diagnostics = [] }; - } - private static AtsContext CreateEmulatorCollisionContext(bool includeEventHubs = true, bool includeServiceBus = true) - { - static AtsTypeInfo Resource(string packageName, string typeName) => new() - { - AtsTypeId = $"{packageName}/{typeName}", - IsInterface = false, - HasExposeMethods = true, - HasExposeProperties = false, - BaseTypeHierarchy = [], - ImplementedInterfaces = [] - }; + var member = Assert.Single(ProjectApi(context, ApiExportPackageName) + .Modules.SelectMany(module => module.Items) + .SelectMany(item => item.Members)); - static AtsCapabilityInfo Emulator(string packageName, AtsTypeInfo target, string optionalTypeId) => new() - { - CapabilityId = $"{packageName}/runAsEmulator", - MethodName = "runAsEmulator", - Parameters = - [ - new AtsParameterInfo - { - Name = "configureContainer", - Type = new AtsTypeRef { TypeId = optionalTypeId, Category = AtsTypeCategory.Primitive }, - IsOptional = true - } - ], - ReturnType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, - TargetTypeId = target.AtsTypeId, - TargetType = new AtsTypeRef { TypeId = target.AtsTypeId, Category = AtsTypeCategory.Handle }, - TargetParameterName = "builder", - ExpandedTargetTypes = [], - ReturnsBuilder = true, - CapabilityKind = AtsCapabilityKind.Method - }; - - var hubsResource = Resource(CollisionPackageA, "EventHubsResource"); - var busResource = Resource(CollisionPackageB, "ServiceBusResource"); - - // The two differ in the type of their shared optional parameter, so the interfaces are not - // mergeable and one of them had to be renamed to make room for the other. - var hubsEmulator = Emulator(CollisionPackageA, hubsResource, AtsConstants.String); - var busEmulator = Emulator(CollisionPackageB, busResource, AtsConstants.Boolean); - - List capabilities = []; - List handleTypes = []; - var exportingAssemblyNames = new Dictionary(StringComparer.Ordinal); + Assert.Equal("configure", member.Name); + Assert.StartsWith($"{member.Name}(", member.Declaration, StringComparison.Ordinal); + } - if (includeEventHubs) - { - capabilities.Add(hubsEmulator); - handleTypes.Add(hubsResource); - exportingAssemblyNames[hubsEmulator.CapabilityId] = CollisionPackageA; - } + [Fact] + public void ApiExportUsesGeneratedSignaturesAndSeparatesReferencedTypes() + { + var context = CreateContextFromBothAssemblies(); + var model = ProjectApi(context, ApiExportPackageName); + var generatedSource = new AtsTypeScriptCodeGenerator() + .GenerateDistributedApplication(context)["aspire.mts"]; + var items = model.Modules.SelectMany(module => module.Items).ToList(); - if (includeServiceBus) - { - capabilities.Add(busEmulator); - handleTypes.Add(busResource); - exportingAssemblyNames[busEmulator.CapabilityId] = CollisionPackageB; - } + Assert.NotEmpty(items); + Assert.All( + items.Where(item => item.Kind != TypeScriptApiItemKind.Augmentation), + item => Assert.Equal(ApiExportPackageName, item.OwningAssemblyName)); + Assert.All( + items.SelectMany(item => item.Members).Where(member => member.Kind == TypeScriptApiItemKind.Method), + member => Assert.Contains(member.Declaration, generatedSource, StringComparison.Ordinal)); - return new AtsContext - { - Capabilities = capabilities, - HandleTypes = handleTypes, - DtoTypes = [], - EnumTypes = [], - ExportedValues = [], - Diagnostics = [], - CapabilityExportingAssemblyNames = exportingAssemblyNames - }; + var itemIds = items.Select(item => item.Id).ToList(); + Assert.Equal(itemIds.Count, itemIds.Distinct(StringComparer.Ordinal).Count()); + Assert.Contains( + model.Declarations, + declaration => declaration.OwningAssemblyName == "Aspire.Hosting"); + Assert.All( + model.Declarations, + declaration => Assert.DoesNotContain('\r', declaration.Content)); } - /// - /// Builds the context the canonical exporter sees for a single package: the package's own - /// capabilities plus the transitive closure of types they reference from other assemblies. - /// This mirrors what RemoteHost passes to the exporter for one Name@Version request. - /// - private static AtsContext CreateOwnershipFilteredContext() - { - return AtsContextFilter.FilterForApiExport( - CreateContextFromBothAssemblies(), - [TestPackageName]); - } + private static TypeScriptApiModel ProjectApi(AtsContext context, string packageName) + => new TypeScriptApiProjector(context).BuildApiModel( + new TypeScriptApiPackageIdentity(packageName, ApiExportPackageVersion), + [packageName], + CancellationToken.None); - private static AtsContext CreateReferencedHandleContext() + private static AtsContext CreateEntryPointContext(string packageName) { - const string ownedTypeId = TestPackageName + "/IOwnedContext"; - const string foreignTypeId = "Foreign.Dependency/IForeignHandle"; - const string resourceTypeId = "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource"; - const string foreignResourceTypeId = "Foreign.Dependency/ForeignResource"; - const string secondForeignResourceTypeId = "Foreign.Dependency/SecondForeignResource"; - const string parameterResourceTypeId = "Foreign.Dependency/ParameterResource"; - const string callbackParameterResourceTypeId = "Foreign.Dependency/CallbackParameterResource"; - const string callbackReturnResourceTypeId = "Foreign.Dependency/CallbackReturnResource"; - const string returnResourceTypeId = "Foreign.Dependency/ReturnResource"; - - var ownedType = new AtsTypeRef - { - TypeId = ownedTypeId, - Category = AtsTypeCategory.Handle, - IsInterface = true - }; - var foreignType = new AtsTypeRef - { - TypeId = foreignTypeId, - Category = AtsTypeCategory.Handle, - IsInterface = true - }; - var resourceType = new AtsTypeRef - { - TypeId = resourceTypeId, - Category = AtsTypeCategory.Handle, - ClrType = typeof(IResource), - IsInterface = true - }; - var foreignResourceType = new AtsTypeRef - { - TypeId = foreignResourceTypeId, - Category = AtsTypeCategory.Handle, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = [resourceType, foreignType] - }; - var secondForeignResourceType = CreateResourceType(secondForeignResourceTypeId, resourceType, foreignType); - var parameterResourceType = CreateResourceType(parameterResourceTypeId, resourceType); - var callbackParameterResourceType = CreateResourceType(callbackParameterResourceTypeId, resourceType); - var callbackReturnResourceType = CreateResourceType(callbackReturnResourceTypeId, resourceType); - var returnResourceType = CreateResourceType(returnResourceTypeId, resourceType); - return new AtsContext { Capabilities = [ new AtsCapabilityInfo { - CapabilityId = TestPackageName + "/getForeign", - MethodName = "getForeign", - OwningTypeName = "IOwnedContext", - Parameters = [], - ReturnType = foreignType, - TargetTypeId = ownedTypeId, - TargetType = ownedType, - ReturnsBuilder = false, - CapabilityKind = AtsCapabilityKind.InstanceMethod - }, - new AtsCapabilityInfo - { - CapabilityId = TestPackageName + "/getConcrete", - MethodName = "getConcrete", - OwningTypeName = "IOwnedContext", - Parameters = [], - ReturnType = foreignResourceType, - TargetTypeId = ownedTypeId, - TargetType = ownedType, - ReturnsBuilder = false, - CapabilityKind = AtsCapabilityKind.InstanceMethod - }, - new AtsCapabilityInfo - { - CapabilityId = TestPackageName + "/waitFor", - MethodName = "waitFor", - OwningTypeName = "IOwnedContext", + CapabilityId = $"{packageName}/startThing", + MethodName = "startThing", Parameters = [ new AtsParameterInfo { - Name = "dependency", - Type = resourceType - } - ], - ReturnType = new AtsTypeRef - { - TypeId = AtsConstants.Void, - Category = AtsTypeCategory.Primitive - }, - TargetTypeId = ownedTypeId, - TargetType = ownedType, - ReturnsBuilder = false, - CapabilityKind = AtsCapabilityKind.InstanceMethod - }, - new AtsCapabilityInfo - { - CapabilityId = TestPackageName + "/waitForForeign", - MethodName = "waitForForeign", - OwningTypeName = "IOwnedContext", - Parameters = - [ + Name = "name", + Type = new AtsTypeRef + { + TypeId = AtsConstants.String, + Category = AtsTypeCategory.Primitive + } + }, new AtsParameterInfo { - Name = "dependency", - Type = foreignType + Name = "retries", + Type = new AtsTypeRef + { + TypeId = AtsConstants.Number, + Category = AtsTypeCategory.Primitive + }, + IsOptional = true } ], ReturnType = new AtsTypeRef @@ -3136,177 +2138,15 @@ private static AtsContext CreateReferencedHandleContext() TypeId = AtsConstants.Void, Category = AtsTypeCategory.Primitive }, - TargetTypeId = ownedTypeId, - TargetType = ownedType, - ReturnsBuilder = false, - CapabilityKind = AtsCapabilityKind.InstanceMethod - }, - new AtsCapabilityInfo - { - CapabilityId = "Foreign.Dependency/getName", - MethodName = "getName", - OwningTypeName = "IForeignHandle", - Parameters = - [ - new AtsParameterInfo - { - Name = "resource", - Type = parameterResourceType - }, - new AtsParameterInfo - { - Name = "configure", - IsCallback = true, - CallbackParameters = - [ - new AtsCallbackParameterInfo - { - Name = "resource", - Type = callbackParameterResourceType - } - ], - CallbackReturnType = callbackReturnResourceType - } - ], - ReturnType = returnResourceType, - TargetTypeId = foreignTypeId, - TargetType = foreignType, - ExpandedTargetTypes = [foreignResourceType, secondForeignResourceType], - ReturnsBuilder = false, - CapabilityKind = AtsCapabilityKind.InstanceMethod - } - ], - HandleTypes = - [ - new AtsTypeInfo - { - AtsTypeId = ownedTypeId, - IsInterface = true - }, - new AtsTypeInfo - { - AtsTypeId = foreignTypeId, - IsInterface = true - }, - new AtsTypeInfo - { - AtsTypeId = foreignResourceTypeId, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = [resourceType, foreignType] - }, - new AtsTypeInfo - { - AtsTypeId = secondForeignResourceTypeId, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = [resourceType, foreignType] - }, - new AtsTypeInfo - { - AtsTypeId = parameterResourceTypeId, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = [resourceType] - }, - new AtsTypeInfo - { - AtsTypeId = callbackParameterResourceTypeId, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = [resourceType] - }, - new AtsTypeInfo - { - AtsTypeId = callbackReturnResourceTypeId, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = [resourceType] - }, - new AtsTypeInfo - { - AtsTypeId = returnResourceTypeId, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = [resourceType] + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.Method } ], + HandleTypes = [], DtoTypes = [], - EnumTypes = [] + EnumTypes = [], + ExportedValues = [], + Diagnostics = [] }; - - static AtsTypeRef CreateResourceType(string typeId, AtsTypeRef resourceType, AtsTypeRef? additionalInterface = null) - { - return new AtsTypeRef - { - TypeId = typeId, - Category = AtsTypeCategory.Handle, - ClrType = typeof(TestRedisResource), - ImplementedInterfaces = additionalInterface is null - ? [resourceType] - : [resourceType, additionalInterface] - }; - } - } - - /// - /// Extracts the member signature lines of every generated export interface block. - /// - /// - /// The generated source declares public surface as interfaces, for example: - /// - /// export interface TestRedisResourceBuilder extends ResourceBuilderBase { - /// /** doc comment */ - /// withPersistence(options?: WithPersistenceOptions): TestRedisResourceBuilderPromise; - /// } - /// - /// Only lines that terminate with ; at brace depth 1 are member signatures; doc - /// comments, blank lines, and nested object literals are skipped. Signatures are stored - /// without the trailing semicolon so they compare directly against exported declarations. - /// - private static Dictionary> ParsePublicInterfaceMembers(string generatedSource) - { - var membersByInterface = new Dictionary>(StringComparer.Ordinal); - - string? currentInterface = null; - var depth = 0; - - foreach (var rawLine in generatedSource.Split('\n')) - { - var line = rawLine.Trim(); - - if (currentInterface is null) - { - // Matches "export interface Name {" and "export interface Name extends Base {". - if (!line.StartsWith("export interface ", StringComparison.Ordinal) || !line.EndsWith('{')) - { - continue; - } - - var header = line["export interface ".Length..^1].Trim(); - var extendsIndex = header.IndexOf(" extends ", StringComparison.Ordinal); - currentInterface = (extendsIndex >= 0 ? header[..extendsIndex] : header).Trim(); - membersByInterface.TryAdd(currentInterface, new HashSet(StringComparer.Ordinal)); - depth = 1; - continue; - } - - depth += line.Count(c => c == '{') - line.Count(c => c == '}'); - - if (depth <= 0) - { - currentInterface = null; - continue; - } - - if (depth == 1 && line.EndsWith(';') && !line.StartsWith('*') && !line.StartsWith("//", StringComparison.Ordinal)) - { - membersByInterface[currentInterface].Add(line[..^1].Trim()); - } - } - - return membersByInterface; - } - - private sealed class PlainObsoleteFixture - { - [Obsolete] - public void Old() - { - } } } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs deleted file mode 100644 index b264cbd2f16..00000000000 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/PriorContractBindingTests.cs +++ /dev/null @@ -1,291 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; -using System.Reflection.Emit; -using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; -using System.Reflection.PortableExecutable; -using System.Text.RegularExpressions; -using Aspire.TypeSystem; - -namespace Aspire.Hosting.CodeGeneration.TypeScript.Tests; - -/// -/// Guards the one compatibility property that keeps TypeScript generation working on a CLI older -/// than the SDK package that carries this generator. -/// -/// -/// -/// Aspire.TypeSystem is force-shared from the apphost server's default load context and -/// freezes its AssemblyVersion at 13.4.5.0, so an already-shipped CLI binds a newer -/// SDK's Aspire.Hosting.CodeGeneration.TypeScript against the CLI's own, older copy of the -/// contract. Anything this assembly names that the older copy lacks fails at run time, and where it -/// fails depends on where it is named: a missing type in a type's interface list or signatures drops -/// only that type (CodeGeneratorResolver salvages the rest), while a missing member in a -/// method body throws when the JIT compiles that method — which -/// on the generation path means TypeScript generation stops working, not just export. -/// -/// -/// The checked-in src/Aspire.TypeSystem/api/Aspire.TypeSystem.cs reference surface is the -/// repository's record of what has shipped, so it is used here as the definition of "members an -/// already-shipped CLI is guaranteed to have". -/// -/// -public partial class PriorContractBindingTests -{ - /// - /// Types allowed to name post-baseline Aspire.TypeSystem API, and why. - /// - private static readonly Dictionary s_allowedTypes = new(StringComparer.Ordinal) - { - [nameof(AtsTypeScriptApiReferenceExporter)] = - "export lives on its own type precisely so an older CLI drops this type and keeps the code generator", - [nameof(AtsContextCompatibility)] = - "the single guarded read, kept behind a runtime probe in a method the JIT may not inline", - }; - - [Fact] - public void GeneratorPathDoesNotBindTypeSystemMembersOutsideTheShippedBaseline() - { - var shippedNames = ReadShippedTypeSystemIdentifiers(); - - var offenders = GetTypeSystemMemberReferencesByDeclaringType() - .SelectMany(entry => entry.Value.Select(reference => (Type: entry.Key, Reference: reference))) - .Where(candidate => !s_allowedTypes.ContainsKey(candidate.Type)) - .Where(candidate => IsPostBaseline(candidate.Reference, shippedNames)) - .Select(candidate => $"{candidate.Type} -> {candidate.Reference.DeclaringType}.{candidate.Reference.MemberName}") - .Order(StringComparer.Ordinal) - .ToArray(); - - Assert.Empty(offenders); - } - - [Fact] - public void CompatibilityShimKeepsThePostBaselineReadOutOfLine() - { - // Inlining the read into its caller would put the member reference back on a method the - // generation path always runs, undoing the probe. - var read = typeof(AtsContextCompatibility).GetMethod( - "ReadCapabilityExportingAssemblyName", - BindingFlags.NonPublic | BindingFlags.Static); - - Assert.NotNull(read); - Assert.Equal(MethodImplAttributes.NoInlining, read.MethodImplementationFlags & MethodImplAttributes.NoInlining); - } - - [Fact] - public void CompatibilityShimReadsTheMapWhenTheLoadedContractHasIt() - { - // The tests run against the in-repo contract, which does expose the map, so this pins that - // the probe has not degraded the current-CLI path into the fallback. - var context = new AtsContext - { - Capabilities = [], - HandleTypes = [], - DtoTypes = [], - EnumTypes = [], - CapabilityExportingAssemblyNames = new Dictionary(StringComparer.Ordinal) - { - ["Contoso.Widgets/addWidget"] = "Contoso.Widgets.Hosting" - } - }; - - Assert.True(AtsContextCompatibility.TryGetCapabilityExportingAssemblyName(context, "Contoso.Widgets/addWidget", out var owner)); - Assert.Equal("Contoso.Widgets.Hosting", owner); - - Assert.False(AtsContextCompatibility.TryGetCapabilityExportingAssemblyName(context, "Contoso.Widgets/addOther", out var missing)); - Assert.Null(missing); - } - - private static bool IsPostBaseline(TypeSystemMemberReference reference, HashSet shippedNames) - { - if (!shippedNames.Contains(reference.DeclaringType)) - { - return true; - } - - // Accessors carry the property name the baseline declares; constructors have no name to - // match, and overload-level checking is out of scope for a name-based comparison. - var memberName = reference.MemberName switch - { - ".ctor" or ".cctor" => null, - ['g', 'e', 't', '_', .. var property] => property, - ['s', 'e', 't', '_', .. var property] => property, - var other => other, - }; - - return memberName is not null && !shippedNames.Contains(memberName); - } - - private static HashSet ReadShippedTypeSystemIdentifiers() - { - // Copied next to the test binary by the project file so this works from any working - // directory, including Helix. - var baselinePath = Path.Combine(AppContext.BaseDirectory, "ApiBaseline", "Aspire.TypeSystem.cs"); - Assert.True(File.Exists(baselinePath), $"Missing shipped API baseline at '{baselinePath}'."); - - return IdentifierRegex() - .Matches(File.ReadAllText(baselinePath)) - .Select(match => match.Value) - .ToHashSet(StringComparer.Ordinal); - } - - /// - /// Collects, per declaring type, the Aspire.TypeSystem members that the generator - /// assembly's method bodies name. - /// - /// - /// Method bodies are read rather than reflected over because the question is what the IL binds - /// to, not what the current contract happens to resolve. Nested types (including compiler - /// generated closures) are attributed to their outermost declaring type so a lambda cannot - /// smuggle a reference past the allow-list. - /// - private static Dictionary> GetTypeSystemMemberReferencesByDeclaringType() - { - var assemblyPath = typeof(AtsTypeScriptCodeGenerator).Assembly.Location; - using var stream = File.OpenRead(assemblyPath); - using var peReader = new PEReader(stream); - var reader = peReader.GetMetadataReader(); - - var references = new Dictionary>(StringComparer.Ordinal); - - foreach (var typeHandle in reader.TypeDefinitions) - { - var typeDefinition = reader.GetTypeDefinition(typeHandle); - var owningTypeName = GetOutermostTypeName(reader, typeDefinition); - - foreach (var methodHandle in typeDefinition.GetMethods()) - { - var method = reader.GetMethodDefinition(methodHandle); - if (method.RelativeVirtualAddress == 0) - { - continue; - } - - var il = peReader.GetMethodBody(method.RelativeVirtualAddress).GetILBytes(); - if (il is null) - { - continue; - } - - foreach (var reference in ReadTypeSystemMemberReferences(reader, il)) - { - if (!references.TryGetValue(owningTypeName, out var list)) - { - references[owningTypeName] = list = []; - } - - list.Add(reference); - } - } - } - - return references; - } - - private static IEnumerable ReadTypeSystemMemberReferences(MetadataReader reader, byte[] il) - { - var offset = 0; - while (offset < il.Length) - { - OpCode opCode; - if (il[offset] == 0xFE) - { - if (offset + 1 >= il.Length || s_twoByteOpCodes.Value[il[offset + 1]] is not { } prefixed) - { - yield break; - } - - opCode = prefixed; - offset += 2; - } - else - { - if (s_oneByteOpCodes.Value[il[offset]] is not { } simple) - { - yield break; - } - - opCode = simple; - offset += 1; - } - - var operandSize = GetOperandSize(opCode, il, offset); - if (opCode.OperandType is OperandType.InlineField or OperandType.InlineMethod or OperandType.InlineTok && - MetadataTokens.EntityHandle(BitConverter.ToInt32(il, offset)) is { Kind: HandleKind.MemberReference } handle) - { - var memberReference = reader.GetMemberReference((MemberReferenceHandle)handle); - if (memberReference.Parent.Kind == HandleKind.TypeReference) - { - var parent = (TypeReferenceHandle)memberReference.Parent; - if (GetAssemblyName(reader, parent) == "Aspire.TypeSystem") - { - yield return new TypeSystemMemberReference( - reader.GetString(reader.GetTypeReference(parent).Name), - reader.GetString(memberReference.Name)); - } - } - } - - offset += operandSize; - } - } - - private static int GetOperandSize(OpCode opCode, byte[] il, int operandOffset) => opCode.OperandType switch - { - OperandType.InlineNone => 0, - OperandType.ShortInlineBrTarget or OperandType.ShortInlineI or OperandType.ShortInlineVar => 1, - OperandType.InlineVar => 2, - OperandType.InlineI8 or OperandType.InlineR => 8, - // A switch is a 4-byte case count followed by that many 4-byte targets. - OperandType.InlineSwitch => 4 + (4 * BitConverter.ToInt32(il, operandOffset)), - _ => 4, - }; - - private static string GetOutermostTypeName(MetadataReader reader, TypeDefinition typeDefinition) - { - while (typeDefinition.IsNested) - { - typeDefinition = reader.GetTypeDefinition(typeDefinition.GetDeclaringType()); - } - - return reader.GetString(typeDefinition.Name); - } - - private static string GetAssemblyName(MetadataReader reader, EntityHandle handle) => handle.Kind switch - { - HandleKind.AssemblyReference => reader.GetString(reader.GetAssemblyReference((AssemblyReferenceHandle)handle).Name), - HandleKind.TypeReference => GetAssemblyName(reader, reader.GetTypeReference((TypeReferenceHandle)handle).ResolutionScope), - _ => string.Empty, - }; - - private static readonly Lazy s_oneByteOpCodes = new(() => BuildOpCodeTable(twoByte: false)); - - private static readonly Lazy s_twoByteOpCodes = new(() => BuildOpCodeTable(twoByte: true)); - - private static OpCode?[] BuildOpCodeTable(bool twoByte) - { - var table = new OpCode?[0x100]; - foreach (var field in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) - { - if (field.GetValue(null) is not OpCode opCode) - { - continue; - } - - var value = unchecked((ushort)opCode.Value); - if (twoByte == value >= 0x100) - { - table[value & 0xFF] = opCode; - } - } - - return table; - } - - [GeneratedRegex("[A-Za-z_][A-Za-z0-9_]*")] - private static partial Regex IdentifierRegex(); - - private readonly record struct TypeSystemMemberReference(string DeclaringType, string MemberName); -} diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts index bea3f6e9feb..1032ac8f00a 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts @@ -180,15 +180,6 @@ export interface AddTestRedisOptions { port?: number; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { - name?: string; - isReadOnly?: boolean; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions { - mode?: TestPersistenceMode; -} - export interface GetStatusAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } @@ -197,6 +188,11 @@ export interface WaitForReadyAsyncOptions { cancellationToken?: AbortSignal | CancellationToken; } +export interface WithDataVolumeOptions { + name?: string; + isReadOnly?: boolean; +} + export interface WithMergeLoggingOptions { enableConsole?: boolean; maxFiles?: number; @@ -216,6 +212,10 @@ export interface WithOptionalStringOptions { enabled?: boolean; } +export interface WithPersistenceOptions { + mode?: TestPersistenceMode; +} + // ============================================================================ // TestCallbackContext // ============================================================================ @@ -807,7 +807,7 @@ export interface TestDatabaseResource { * Adds a data volume * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestDatabaseResourcePromise; + withDataVolume(options?: WithDataVolumeOptions): TestDatabaseResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestDatabaseResourcePromise; /** Adds a categorized label to the resource */ @@ -875,7 +875,7 @@ export interface TestDatabaseResourcePromise extends PromiseLike obj.withCancellableOperation(operation)), this._client); } - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestDatabaseResourcePromise { + withDataVolume(options?: WithDataVolumeOptions): TestDatabaseResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } @@ -1476,7 +1476,7 @@ export interface TestRedisResource { * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -1543,7 +1543,7 @@ export interface TestRedisResource { * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1581,7 +1581,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -1648,7 +1648,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -1720,7 +1720,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -2137,7 +2137,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -2300,7 +2300,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } @@ -2404,7 +2404,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt deleted file mode 100644 index 181d7974e2f..00000000000 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiDeclarations.verified.txt +++ /dev/null @@ -1,991 +0,0 @@ -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource -export interface CSharpAppResource { - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; - withConfig(config: TestConfigDto): CSharpAppResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; - withCreatedAt(createdAt: string): CSharpAppResourcePromise; - withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; - withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; - withStatus(status: TestResourceStatus): CSharpAppResourcePromise; - withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; - testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; - withDependency(dependency: Awaitable): CSharpAppResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): CSharpAppResourcePromise; - withEndpoints(endpoints: string[]): CSharpAppResourcePromise; - withEnvironmentVariables(variables: Record): CSharpAppResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): CSharpAppResourcePromise; - withMergeLabel(label: string): CSharpAppResourcePromise; - withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; - withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise -export interface CSharpAppResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise; - withConfig(config: TestConfigDto): CSharpAppResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): CSharpAppResourcePromise; - withCreatedAt(createdAt: string): CSharpAppResourcePromise; - withModifiedAt(modifiedAt: string): CSharpAppResourcePromise; - withCorrelationId(correlationId: string): CSharpAppResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise; - withStatus(status: TestResourceStatus): CSharpAppResourcePromise; - withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): CSharpAppResourcePromise; - testWaitFor(dependency: Awaitable): CSharpAppResourcePromise; - withDependency(dependency: Awaitable): CSharpAppResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): CSharpAppResourcePromise; - withEndpoints(endpoints: string[]): CSharpAppResourcePromise; - withEnvironmentVariables(variables: Record): CSharpAppResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): CSharpAppResourcePromise; - withMergeLabel(label: string): CSharpAppResourcePromise; - withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise; - withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource -export interface ContainerRegistryResource { - withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; - withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; - withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; - withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; - withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; - withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; - withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; - testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; - withDependency(dependency: Awaitable): ContainerRegistryResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerRegistryResourcePromise; - withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerRegistryResourcePromise; - withMergeLabel(label: string): ContainerRegistryResourcePromise; - withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise -export interface ContainerRegistryResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise; - withConfig(config: TestConfigDto): ContainerRegistryResourcePromise; - withCreatedAt(createdAt: string): ContainerRegistryResourcePromise; - withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise; - withCorrelationId(correlationId: string): ContainerRegistryResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise; - withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise; - withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ContainerRegistryResourcePromise; - testWaitFor(dependency: Awaitable): ContainerRegistryResourcePromise; - withDependency(dependency: Awaitable): ContainerRegistryResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerRegistryResourcePromise; - withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerRegistryResourcePromise; - withMergeLabel(label: string): ContainerRegistryResourcePromise; - withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource -export interface ContainerResource { - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; - withConfig(config: TestConfigDto): ContainerResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; - withCreatedAt(createdAt: string): ContainerResourcePromise; - withModifiedAt(modifiedAt: string): ContainerResourcePromise; - withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; - withStatus(status: TestResourceStatus): ContainerResourcePromise; - withNestedConfig(config: TestNestedDto): ContainerResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; - testWaitFor(dependency: Awaitable): ContainerResourcePromise; - withDependency(dependency: Awaitable): ContainerResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerResourcePromise; - withEndpoints(endpoints: string[]): ContainerResourcePromise; - withEnvironmentVariables(variables: Record): ContainerResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerResourcePromise; - withMergeLabel(label: string): ContainerResourcePromise; - withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise -export interface ContainerResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise; - withConfig(config: TestConfigDto): ContainerResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ContainerResourcePromise; - withCreatedAt(createdAt: string): ContainerResourcePromise; - withModifiedAt(modifiedAt: string): ContainerResourcePromise; - withCorrelationId(correlationId: string): ContainerResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise; - withStatus(status: TestResourceStatus): ContainerResourcePromise; - withNestedConfig(config: TestNestedDto): ContainerResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ContainerResourcePromise; - testWaitFor(dependency: Awaitable): ContainerResourcePromise; - withDependency(dependency: Awaitable): ContainerResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ContainerResourcePromise; - withEndpoints(endpoints: string[]): ContainerResourcePromise; - withEnvironmentVariables(variables: Record): ContainerResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ContainerResourcePromise; - withMergeLabel(label: string): ContainerResourcePromise; - withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder -export interface DistributedApplicationBuilder { - addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; - addTestVault(name: string): TestVaultResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise -export interface DistributedApplicationBuilderPromise { - addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise; - addTestVault(name: string): TestVaultResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource -export interface DotnetToolResource { - withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; - withConfig(config: TestConfigDto): DotnetToolResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; - withCreatedAt(createdAt: string): DotnetToolResourcePromise; - withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; - withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; - withStatus(status: TestResourceStatus): DotnetToolResourcePromise; - withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; - testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; - withDependency(dependency: Awaitable): DotnetToolResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): DotnetToolResourcePromise; - withEndpoints(endpoints: string[]): DotnetToolResourcePromise; - withEnvironmentVariables(variables: Record): DotnetToolResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): DotnetToolResourcePromise; - withMergeLabel(label: string): DotnetToolResourcePromise; - withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; - withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise -export interface DotnetToolResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise; - withConfig(config: TestConfigDto): DotnetToolResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): DotnetToolResourcePromise; - withCreatedAt(createdAt: string): DotnetToolResourcePromise; - withModifiedAt(modifiedAt: string): DotnetToolResourcePromise; - withCorrelationId(correlationId: string): DotnetToolResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise; - withStatus(status: TestResourceStatus): DotnetToolResourcePromise; - withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): DotnetToolResourcePromise; - testWaitFor(dependency: Awaitable): DotnetToolResourcePromise; - withDependency(dependency: Awaitable): DotnetToolResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): DotnetToolResourcePromise; - withEndpoints(endpoints: string[]): DotnetToolResourcePromise; - withEnvironmentVariables(variables: Record): DotnetToolResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): DotnetToolResourcePromise; - withMergeLabel(label: string): DotnetToolResourcePromise; - withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise; - withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource -export interface ExecutableResource { - withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; - withConfig(config: TestConfigDto): ExecutableResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; - withCreatedAt(createdAt: string): ExecutableResourcePromise; - withModifiedAt(modifiedAt: string): ExecutableResourcePromise; - withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; - withStatus(status: TestResourceStatus): ExecutableResourcePromise; - withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; - testWaitFor(dependency: Awaitable): ExecutableResourcePromise; - withDependency(dependency: Awaitable): ExecutableResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExecutableResourcePromise; - withEndpoints(endpoints: string[]): ExecutableResourcePromise; - withEnvironmentVariables(variables: Record): ExecutableResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExecutableResourcePromise; - withMergeLabel(label: string): ExecutableResourcePromise; - withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise -export interface ExecutableResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise; - withConfig(config: TestConfigDto): ExecutableResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ExecutableResourcePromise; - withCreatedAt(createdAt: string): ExecutableResourcePromise; - withModifiedAt(modifiedAt: string): ExecutableResourcePromise; - withCorrelationId(correlationId: string): ExecutableResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise; - withStatus(status: TestResourceStatus): ExecutableResourcePromise; - withNestedConfig(config: TestNestedDto): ExecutableResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ExecutableResourcePromise; - testWaitFor(dependency: Awaitable): ExecutableResourcePromise; - withDependency(dependency: Awaitable): ExecutableResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExecutableResourcePromise; - withEndpoints(endpoints: string[]): ExecutableResourcePromise; - withEnvironmentVariables(variables: Record): ExecutableResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExecutableResourcePromise; - withMergeLabel(label: string): ExecutableResourcePromise; - withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource -export interface ExternalServiceResource { - withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; - withConfig(config: TestConfigDto): ExternalServiceResourcePromise; - withCreatedAt(createdAt: string): ExternalServiceResourcePromise; - withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; - withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; - withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; - withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; - testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; - withDependency(dependency: Awaitable): ExternalServiceResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExternalServiceResourcePromise; - withEndpoints(endpoints: string[]): ExternalServiceResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExternalServiceResourcePromise; - withMergeLabel(label: string): ExternalServiceResourcePromise; - withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise -export interface ExternalServiceResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise; - withConfig(config: TestConfigDto): ExternalServiceResourcePromise; - withCreatedAt(createdAt: string): ExternalServiceResourcePromise; - withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise; - withCorrelationId(correlationId: string): ExternalServiceResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise; - withStatus(status: TestResourceStatus): ExternalServiceResourcePromise; - withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ExternalServiceResourcePromise; - testWaitFor(dependency: Awaitable): ExternalServiceResourcePromise; - withDependency(dependency: Awaitable): ExternalServiceResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ExternalServiceResourcePromise; - withEndpoints(endpoints: string[]): ExternalServiceResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ExternalServiceResourcePromise; - withMergeLabel(label: string): ExternalServiceResourcePromise; - withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource -export interface ParameterResource { - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; - withConfig(config: TestConfigDto): ParameterResourcePromise; - withCreatedAt(createdAt: string): ParameterResourcePromise; - withModifiedAt(modifiedAt: string): ParameterResourcePromise; - withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; - withStatus(status: TestResourceStatus): ParameterResourcePromise; - withNestedConfig(config: TestNestedDto): ParameterResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; - testWaitFor(dependency: Awaitable): ParameterResourcePromise; - withDependency(dependency: Awaitable): ParameterResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ParameterResourcePromise; - withEndpoints(endpoints: string[]): ParameterResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ParameterResourcePromise; - withMergeLabel(label: string): ParameterResourcePromise; - withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise -export interface ParameterResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise; - withConfig(config: TestConfigDto): ParameterResourcePromise; - withCreatedAt(createdAt: string): ParameterResourcePromise; - withModifiedAt(modifiedAt: string): ParameterResourcePromise; - withCorrelationId(correlationId: string): ParameterResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise; - withStatus(status: TestResourceStatus): ParameterResourcePromise; - withNestedConfig(config: TestNestedDto): ParameterResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ParameterResourcePromise; - testWaitFor(dependency: Awaitable): ParameterResourcePromise; - withDependency(dependency: Awaitable): ParameterResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ParameterResourcePromise; - withEndpoints(endpoints: string[]): ParameterResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ParameterResourcePromise; - withMergeLabel(label: string): ParameterResourcePromise; - withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource -export interface ProjectResource { - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; - withConfig(config: TestConfigDto): ProjectResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; - withCreatedAt(createdAt: string): ProjectResourcePromise; - withModifiedAt(modifiedAt: string): ProjectResourcePromise; - withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; - withStatus(status: TestResourceStatus): ProjectResourcePromise; - withNestedConfig(config: TestNestedDto): ProjectResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; - testWaitFor(dependency: Awaitable): ProjectResourcePromise; - withDependency(dependency: Awaitable): ProjectResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ProjectResourcePromise; - withEndpoints(endpoints: string[]): ProjectResourcePromise; - withEnvironmentVariables(variables: Record): ProjectResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ProjectResourcePromise; - withMergeLabel(label: string): ProjectResourcePromise; - withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise -export interface ProjectResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise; - withConfig(config: TestConfigDto): ProjectResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ProjectResourcePromise; - withCreatedAt(createdAt: string): ProjectResourcePromise; - withModifiedAt(modifiedAt: string): ProjectResourcePromise; - withCorrelationId(correlationId: string): ProjectResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise; - withStatus(status: TestResourceStatus): ProjectResourcePromise; - withNestedConfig(config: TestNestedDto): ProjectResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ProjectResourcePromise; - testWaitFor(dependency: Awaitable): ProjectResourcePromise; - withDependency(dependency: Awaitable): ProjectResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ProjectResourcePromise; - withEndpoints(endpoints: string[]): ProjectResourcePromise; - withEnvironmentVariables(variables: Record): ProjectResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ProjectResourcePromise; - withMergeLabel(label: string): ProjectResourcePromise; - withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource -export interface Resource { - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; - withConfig(config: TestConfigDto): ResourcePromise; - withCreatedAt(createdAt: string): ResourcePromise; - withModifiedAt(modifiedAt: string): ResourcePromise; - withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; - withStatus(status: TestResourceStatus): ResourcePromise; - withNestedConfig(config: TestNestedDto): ResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; - testWaitFor(dependency: Awaitable): ResourcePromise; - withDependency(dependency: Awaitable): ResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ResourcePromise; - withEndpoints(endpoints: string[]): ResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ResourcePromise; - withMergeLabel(label: string): ResourcePromise; - withMergeLabelCategorized(label: string, category: string): ResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise -export interface ResourcePromise { - withOptionalString(options?: WithOptionalStringOptions): ResourcePromise; - withConfig(config: TestConfigDto): ResourcePromise; - withCreatedAt(createdAt: string): ResourcePromise; - withModifiedAt(modifiedAt: string): ResourcePromise; - withCorrelationId(correlationId: string): ResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise; - withStatus(status: TestResourceStatus): ResourcePromise; - withNestedConfig(config: TestNestedDto): ResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): ResourcePromise; - testWaitFor(dependency: Awaitable): ResourcePromise; - withDependency(dependency: Awaitable): ResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): ResourcePromise; - withEndpoints(endpoints: string[]): ResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): ResourcePromise; - withMergeLabel(label: string): ResourcePromise; - withMergeLabelCategorized(label: string, category: string): ResourcePromise; - withMergeEndpoint(endpointName: string, port: number): ResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString -export interface ResourceWithConnectionString { - withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise; - withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionStringPromise -export interface ResourceWithConnectionStringPromise { - withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise; - withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironment -export interface ResourceWithEnvironment { - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ResourceWithEnvironmentPromise; - withEnvironmentVariables(variables: Record): ResourceWithEnvironmentPromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironmentPromise -export interface ResourceWithEnvironmentPromise { - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): ResourceWithEnvironmentPromise; - withEnvironmentVariables(variables: Record): ResourceWithEnvironmentPromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestConfigDto -export interface TestConfigDto { - name?: string; - port?: number; - enabled?: boolean; - optionalField?: string | null; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestDeeplyNestedDto -export interface TestDeeplyNestedDto { - nestedData?: Record; - metadataArray?: Record[]; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestNestedDto -export interface TestNestedDto { - id?: string; - config?: TestConfigDto; - tags?: string[]; - counts?: Record; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestPersistenceMode -export enum TestPersistenceMode { - None = "None", - Volume = "Volume", - Bind = "Bind", -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestResourceStatus -export enum TestResourceStatus { - Pending = "Pending", - Running = "Running", - Stopped = "Stopped", - Failed = "Failed", -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:handle:ITestVaultResourceHandle -export type ITestVaultResourceHandle = Handle<'Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.ITestVaultResource'>; - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCallbackContext -export interface TestCallbackContext { - toJSON(): MarshalledHandle; - name: { get: () => Promise; set: (value: string | null) => Promise }; - value: { get: () => Promise; set: (value: number) => Promise }; - cancellationToken: { get: () => Promise; set: (value: AbortSignal | CancellationToken) => Promise }; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContext -export interface TestCollectionContext { - toJSON(): MarshalledHandle; - items(): Promise>; - metadata(): Promise>; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContextPromise -export interface TestCollectionContextPromise extends PromiseLike { - items(): Promise>; - metadata(): Promise>; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource -export interface TestDatabaseResource extends ResourceBuilderBase { - toJSON(): MarshalledHandle; - withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; - withConfig(config: TestConfigDto): TestDatabaseResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; - withCreatedAt(createdAt: string): TestDatabaseResourcePromise; - withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; - withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; - withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; - withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; - testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; - withDependency(dependency: Awaitable): TestDatabaseResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestDatabaseResourcePromise; - withEndpoints(endpoints: string[]): TestDatabaseResourcePromise; - withEnvironmentVariables(variables: Record): TestDatabaseResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestDatabaseResourcePromise; - withMergeLabel(label: string): TestDatabaseResourcePromise; - withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; - withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise -export interface TestDatabaseResourcePromise extends PromiseLike { - withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise; - withConfig(config: TestConfigDto): TestDatabaseResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestDatabaseResourcePromise; - withCreatedAt(createdAt: string): TestDatabaseResourcePromise; - withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise; - withCorrelationId(correlationId: string): TestDatabaseResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise; - withStatus(status: TestResourceStatus): TestDatabaseResourcePromise; - withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): TestDatabaseResourcePromise; - testWaitFor(dependency: Awaitable): TestDatabaseResourcePromise; - withDependency(dependency: Awaitable): TestDatabaseResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestDatabaseResourcePromise; - withEndpoints(endpoints: string[]): TestDatabaseResourcePromise; - withEnvironmentVariables(variables: Record): TestDatabaseResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestDatabaseResourcePromise; - withMergeLabel(label: string): TestDatabaseResourcePromise; - withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise; - withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext -export interface TestEnvironmentContext { - toJSON(): MarshalledHandle; - name: { get: () => Promise; set: (value: string) => Promise }; - description: { get: () => Promise; set: (value: string | null) => Promise }; - priority: { get: () => Promise; set: (value: number) => Promise }; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestMutableCollectionContext -export interface TestMutableCollectionContext { - toJSON(): MarshalledHandle; - readonly tags: AspireList; - readonly counts: AspireDict; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource -export interface TestRedisResource extends ResourceBuilderBase { - toJSON(): MarshalledHandle; - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; - withConfig(config: TestConfigDto): TestRedisResourcePromise; - getTags(): Promise>; - getMetadata(): Promise>; - withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withCreatedAt(createdAt: string): TestRedisResourcePromise; - withModifiedAt(modifiedAt: string): TestRedisResourcePromise; - withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; - withStatus(status: TestResourceStatus): TestRedisResourcePromise; - withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; - testWaitFor(dependency: Awaitable): TestRedisResourcePromise; - getEndpoints(): Promise; - withConnectionStringDirect(connectionString: string): TestRedisResourcePromise; - withRedisSpecific(option: string): TestRedisResourcePromise; - withDependency(dependency: Awaitable): TestRedisResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; - withEndpoints(endpoints: string[]): TestRedisResourcePromise; - withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: GetStatusAsyncOptions): Promise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; - withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; - withMergeLabel(label: string): TestRedisResourcePromise; - withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; - withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise -export interface TestRedisResourcePromise extends PromiseLike { - addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise; - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; - withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise; - withConfig(config: TestConfigDto): TestRedisResourcePromise; - getTags(): Promise>; - getMetadata(): Promise>; - withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withCreatedAt(createdAt: string): TestRedisResourcePromise; - withModifiedAt(modifiedAt: string): TestRedisResourcePromise; - withCorrelationId(correlationId: string): TestRedisResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise; - withStatus(status: TestResourceStatus): TestRedisResourcePromise; - withNestedConfig(config: TestNestedDto): TestRedisResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): TestRedisResourcePromise; - testWaitFor(dependency: Awaitable): TestRedisResourcePromise; - getEndpoints(): Promise; - withConnectionStringDirect(connectionString: string): TestRedisResourcePromise; - withRedisSpecific(option: string): TestRedisResourcePromise; - withDependency(dependency: Awaitable): TestRedisResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestRedisResourcePromise; - withEndpoints(endpoints: string[]): TestRedisResourcePromise; - withEnvironmentVariables(variables: Record): TestRedisResourcePromise; - getStatusAsync(options?: GetStatusAsyncOptions): Promise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestRedisResourcePromise; - waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise; - withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) => Promise): TestRedisResourcePromise; - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; - withMergeLabel(label: string): TestRedisResourcePromise; - withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise; - withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext -export interface TestResourceContext { - toJSON(): MarshalledHandle; - name: { get: () => Promise; set: (value: string) => Promise }; - value: { get: () => Promise; set: (value: number) => Promise }; - getValueAsync(): Promise; - setValueAsync(value: string): TestResourceContextPromise; - validateAsync(): Promise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContextPromise -export interface TestResourceContextPromise extends PromiseLike { - name: { get: () => Promise; set: (value: string) => Promise }; - value: { get: () => Promise; set: (value: number) => Promise }; - getValueAsync(): Promise; - setValueAsync(value: string): TestResourceContextPromise; - validateAsync(): Promise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource -export interface TestVaultResource extends ResourceBuilderBase { - toJSON(): MarshalledHandle; - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; - withConfig(config: TestConfigDto): TestVaultResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; - withCreatedAt(createdAt: string): TestVaultResourcePromise; - withModifiedAt(modifiedAt: string): TestVaultResourcePromise; - withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; - withStatus(status: TestResourceStatus): TestVaultResourcePromise; - withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; - testWaitFor(dependency: Awaitable): TestVaultResourcePromise; - withDependency(dependency: Awaitable): TestVaultResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestVaultResourcePromise; - withEndpoints(endpoints: string[]): TestVaultResourcePromise; - withEnvironmentVariables(variables: Record): TestVaultResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestVaultResourcePromise; - withVaultDirect(option: string): TestVaultResourcePromise; - withMergeLabel(label: string): TestVaultResourcePromise; - withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; - withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise -export interface TestVaultResourcePromise extends PromiseLike { - withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise; - withConfig(config: TestConfigDto): TestVaultResourcePromise; - testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) => Promise): TestVaultResourcePromise; - withCreatedAt(createdAt: string): TestVaultResourcePromise; - withModifiedAt(modifiedAt: string): TestVaultResourcePromise; - withCorrelationId(correlationId: string): TestVaultResourcePromise; - withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise; - withStatus(status: TestResourceStatus): TestVaultResourcePromise; - withNestedConfig(config: TestNestedDto): TestVaultResourcePromise; - withValidator(validator: (arg: TestResourceContext) => Promise): TestVaultResourcePromise; - testWaitFor(dependency: Awaitable): TestVaultResourcePromise; - withDependency(dependency: Awaitable): TestVaultResourcePromise; - withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable): TestVaultResourcePromise; - withEndpoints(endpoints: string[]): TestVaultResourcePromise; - withEnvironmentVariables(variables: Record): TestVaultResourcePromise; - withCancellableOperation(operation: (arg: CancellationToken) => Promise): TestVaultResourcePromise; - withVaultDirect(option: string): TestVaultResourcePromise; - withMergeLabel(label: string): TestVaultResourcePromise; - withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise; - withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise; - withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise; - withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise; - withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise; - withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise; - withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions -export interface AddTestChildDatabaseOptions { - databaseName?: string; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions -export interface AddTestRedisOptions { - port?: number; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { - name?: string; - isReadOnly?: boolean; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions { - mode?: TestPersistenceMode; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions -export interface GetStatusAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions -export interface WaitForReadyAsyncOptions { - cancellationToken?: AbortSignal | CancellationToken; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions -export interface WithMergeLoggingOptions { - enableConsole?: boolean; - maxFiles?: number; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions -export interface WithMergeLoggingPathOptions { - enableConsole?: boolean; - maxFiles?: number; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions -export interface WithOptionalCallbackOptions { - callback?: (arg: TestCallbackContext) => Promise; -} - -// Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions -export interface WithOptionalStringOptions { - value?: string; - enabled?: boolean; -} - -// Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle -export type CommandLineArgsCallbackContextHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.CommandLineArgsCallbackContext'>; - -// Aspire.Hosting:handle:EndpointReferenceHandle -export type EndpointReferenceHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointReference'>; - -// Aspire.Hosting:handle:EndpointUpdateContextHandle -export type EndpointUpdateContextHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointUpdateContext'>; - -// Aspire.Hosting:handle:ReferenceExpressionHandle -export type ReferenceExpressionHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.ReferenceExpression'>; - -// Aspire.Hosting:handle:ResourceEndpointsAllocatedEventHandle -export type ResourceEndpointsAllocatedEventHandle = Handle<'Aspire.Hosting/Aspire.Hosting.ApplicationModel.ResourceEndpointsAllocatedEvent'>; - -// Aspire.Hosting:opaque:CSharpAppResource -export interface CSharpAppResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:CSharpAppResourcePromise -export interface CSharpAppResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ContainerRegistryResource -export interface ContainerRegistryResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ContainerRegistryResourcePromise -export interface ContainerRegistryResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ContainerResource -export interface ContainerResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ContainerResourcePromise -export interface ContainerResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:DistributedApplicationBuilder -export interface DistributedApplicationBuilder extends HandleReference {} - -// Aspire.Hosting:opaque:DistributedApplicationBuilderPromise -export interface DistributedApplicationBuilderPromise extends PromiseLike {} - -// Aspire.Hosting:opaque:DotnetToolResource -export interface DotnetToolResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:DotnetToolResourcePromise -export interface DotnetToolResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ExecutableResource -export interface ExecutableResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ExecutableResourcePromise -export interface ExecutableResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ExternalServiceResource -export interface ExternalServiceResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ExternalServiceResourcePromise -export interface ExternalServiceResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ParameterResource -export interface ParameterResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ParameterResourcePromise -export interface ParameterResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ProjectResource -export interface ProjectResource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ProjectResourcePromise -export interface ProjectResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:Resource -export interface Resource extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ResourcePromise -export interface ResourcePromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ResourceWithArgs -export interface ResourceWithArgs extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ResourceWithArgsPromise -export interface ResourceWithArgsPromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ResourceWithConnectionString -export interface ResourceWithConnectionString extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ResourceWithConnectionStringPromise -export interface ResourceWithConnectionStringPromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ResourceWithEndpoints -export interface ResourceWithEndpoints extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ResourceWithEndpointsPromise -export interface ResourceWithEndpointsPromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ResourceWithEnvironment -export interface ResourceWithEnvironment extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ResourceWithEnvironmentPromise -export interface ResourceWithEnvironmentPromise extends PromiseLike {} - -// Aspire.Hosting:opaque:ResourceWithWaitSupport -export interface ResourceWithWaitSupport extends ResourceBuilderBase {} - -// Aspire.Hosting:opaque:ResourceWithWaitSupportPromise -export interface ResourceWithWaitSupportPromise extends PromiseLike {} - -// aspire:runtime:base -export type Awaitable = T | PromiseLike; -export interface MarshalledHandle { $handle: string; $type: string; } -export interface Handle { readonly $handle: string; readonly $type: T; toJSON(): MarshalledHandle; } -export interface HandleReference { toJSON(): MarshalledHandle; } -export interface AbortSignal { readonly aborted: boolean; } -export interface CancellationToken { readonly aborted: boolean; } -export enum InputType { Text = 'Text', SecretText = 'SecretText', Choice = 'Choice', Boolean = 'Boolean', Number = 'Number' } -export interface ReferenceExpression { readonly value: Promise; } -export interface AspireList extends HandleReference { get(index: number): Promise; } -export interface AspireDict extends HandleReference { get(key: TKey): Promise; } -export interface ResourceBuilderBase extends HandleReference {} -export interface InteractionInput { readonly name: string; } -export interface InteractionInputCollection extends HandleReference {} -export interface InteractionInputCollectionPromise extends PromiseLike {} -export interface AspireClientRpc { readonly connected: boolean; invokeCapability(capabilityId: string, args?: Record): Promise; } \ No newline at end of file diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json deleted file mode 100644 index 9bebfef2df9..00000000000 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.ApiExport.verified.json +++ /dev/null @@ -1,6809 +0,0 @@ -{ - "schemaVersion": 1, - "language": "typescript", - "package": { - "name": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "version": "13.5.0" - }, - "modules": [ - { - "name": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "items": [ - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:CSharpAppResource", - "kind": "augmentation", - "name": "CSharpAppResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.CSharpAppResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface CSharpAppResource extends ResourceBuilderBase", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:CSharpAppResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "CSharpAppResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:CSharpAppResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "CSharpAppResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "CSharpAppResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "CSharpAppResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:CSharpAppResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "CSharpAppResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "CSharpAppResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "CSharpAppResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "CSharpAppResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "CSharpAppResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "CSharpAppResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "CSharpAppResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "CSharpAppResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "CSharpAppResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "CSharpAppResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:CSharpAppResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "CSharpAppResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ContainerRegistryResource", - "kind": "augmentation", - "name": "ContainerRegistryResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerRegistryResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ContainerRegistryResource extends ResourceBuilderBase", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ContainerRegistryResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerRegistryResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerRegistryResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ContainerRegistryResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "ContainerRegistryResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ContainerResource", - "kind": "augmentation", - "name": "ContainerResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ContainerResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ContainerResource extends ResourceBuilderBase", - "summary": "A resource that represents a specified container.", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ContainerResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "ContainerResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "ContainerResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "ContainerResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "ContainerResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "ContainerResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "ContainerResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "ContainerResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "ContainerResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "ContainerResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "ContainerResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "ContainerResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "ContainerResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "ContainerResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "ContainerResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "ContainerResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "ContainerResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "ContainerResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "ContainerResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "ContainerResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "ContainerResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "ContainerResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "ContainerResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:ContainerResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "ContainerResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ContainerResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "ContainerResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:DistributedApplicationBuilder", - "kind": "augmentation", - "name": "DistributedApplicationBuilder", - "typeId": "Aspire.Hosting/Aspire.Hosting.IDistributedApplicationBuilder", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface DistributedApplicationBuilder", - "summary": "A builder for creating instances of {@ats-ref type:DistributedApplication}.", - "members": [ - { - "id": "method:DistributedApplicationBuilder.addTestRedis", - "kind": "method", - "name": "addTestRedis", - "declaration": "addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestRedis", - "returnType": "TestRedisResourcePromise", - "summary": "Adds a test Redis resource from ATS documentation.", - "parameters": [ - { - "name": "name", - "type": "string", - "optional": false, - "summary": "The ATS resource name." - }, - { - "name": "options", - "type": "AddTestRedisOptions", - "optional": true - } - ] - }, - { - "id": "method:DistributedApplicationBuilder.addTestVault", - "kind": "method", - "name": "addTestVault", - "declaration": "addTestVault(name: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestVault", - "returnType": "TestVaultResourcePromise", - "summary": "Adds a test vault resource", - "parameters": [ - { - "name": "name", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:DotnetToolResource", - "kind": "augmentation", - "name": "DotnetToolResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.DotnetToolResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface DotnetToolResource extends ResourceBuilderBase", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:DotnetToolResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "DotnetToolResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:DotnetToolResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "DotnetToolResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "DotnetToolResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "DotnetToolResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:DotnetToolResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "DotnetToolResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "DotnetToolResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "DotnetToolResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "DotnetToolResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "DotnetToolResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "DotnetToolResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "DotnetToolResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "DotnetToolResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "DotnetToolResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "DotnetToolResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:DotnetToolResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "DotnetToolResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ExecutableResource", - "kind": "augmentation", - "name": "ExecutableResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ExecutableResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ExecutableResource extends ResourceBuilderBase", - "summary": "A resource that represents a specified executable process.", - "remarks": "You can run any executable command using its full path.\nAs a security feature, Aspire doesn\u0027t run executable unless the command is located in a path listed in the PATH environment variable.\nTo run an executable file that\u0027s in the current directory, specify the full path or use the relative path \u0060./\u0060 to represent the current directory.", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ExecutableResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "ExecutableResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:ExecutableResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "ExecutableResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "ExecutableResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "ExecutableResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "ExecutableResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "ExecutableResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "ExecutableResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:ExecutableResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "ExecutableResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "ExecutableResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "ExecutableResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "ExecutableResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "ExecutableResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "ExecutableResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "ExecutableResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "ExecutableResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "ExecutableResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "ExecutableResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "ExecutableResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "ExecutableResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "ExecutableResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "ExecutableResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:ExecutableResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "ExecutableResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:ExecutableResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "ExecutableResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ExecutableResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "ExecutableResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ExternalServiceResource", - "kind": "augmentation", - "name": "ExternalServiceResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ExternalServiceResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ExternalServiceResource extends ResourceBuilderBase", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ExternalServiceResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "ExternalServiceResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:ExternalServiceResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "ExternalServiceResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "ExternalServiceResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "ExternalServiceResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:ExternalServiceResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "ExternalServiceResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "ExternalServiceResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "ExternalServiceResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "ExternalServiceResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "ExternalServiceResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "ExternalServiceResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "ExternalServiceResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "ExternalServiceResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "ExternalServiceResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ExternalServiceResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "ExternalServiceResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ParameterResource", - "kind": "augmentation", - "name": "ParameterResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ParameterResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ParameterResource extends ResourceBuilderBase", - "summary": "Represents a parameter resource.", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ParameterResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "ParameterResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:ParameterResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "ParameterResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "ParameterResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "ParameterResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "ParameterResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "ParameterResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:ParameterResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "ParameterResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "ParameterResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "ParameterResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "ParameterResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "ParameterResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "ParameterResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "ParameterResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "ParameterResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "ParameterResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "ParameterResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "ParameterResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "ParameterResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "ParameterResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:ParameterResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "ParameterResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:ParameterResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "ParameterResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ParameterResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "ParameterResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ProjectResource", - "kind": "augmentation", - "name": "ProjectResource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.ProjectResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ProjectResource extends ResourceBuilderBase", - "summary": "A resource that represents a specified .NET project.", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ProjectResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "ProjectResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:ProjectResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "ProjectResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "ProjectResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "ProjectResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "ProjectResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "ProjectResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "ProjectResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:ProjectResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "ProjectResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "ProjectResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "ProjectResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "ProjectResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "ProjectResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "ProjectResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "ProjectResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "ProjectResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "ProjectResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "ProjectResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "ProjectResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "ProjectResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "ProjectResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "ProjectResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:ProjectResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "ProjectResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:ProjectResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "ProjectResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:ProjectResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "ProjectResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:Resource", - "kind": "augmentation", - "name": "Resource", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResource", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface Resource extends ResourceBuilderBase", - "summary": "Represents a resource that can be hosted by an application.", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:Resource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "ResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:Resource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "ResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:Resource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "ResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:Resource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "ResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:Resource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "ResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:Resource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "ResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:Resource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "ResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:Resource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "ResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:Resource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "ResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:Resource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "ResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:Resource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "ResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:Resource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "ResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:Resource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "ResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:Resource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "ResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:Resource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "ResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:Resource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "ResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:Resource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "ResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:Resource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "ResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:Resource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "ResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:Resource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "ResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:Resource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "ResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:Resource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "ResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ResourceWithConnectionString", - "kind": "augmentation", - "name": "ResourceWithConnectionString", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithConnectionString", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ResourceWithConnectionString extends ResourceBuilderBase", - "summary": "Represents a resource that has a connection string associated with it.", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ResourceWithConnectionString.withConnectionString", - "kind": "method", - "name": "withConnectionString", - "declaration": "withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionString", - "returnType": "ResourceWithConnectionStringPromise", - "summary": "Sets the connection string using a reference expression", - "parameters": [ - { - "name": "connectionString", - "type": "ReferenceExpression", - "optional": false - } - ] - }, - { - "id": "method:ResourceWithConnectionString.withConnectionStringDirect", - "kind": "method", - "name": "withConnectionStringDirect", - "declaration": "withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionStringDirect", - "returnType": "ResourceWithConnectionStringPromise", - "summary": "Sets connection string using direct interface target", - "parameters": [ - { - "name": "connectionString", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "augmentation:Aspire.Hosting.CodeGeneration.TypeScript.Tests:ResourceWithEnvironment", - "kind": "augmentation", - "name": "ResourceWithEnvironment", - "typeId": "Aspire.Hosting/Aspire.Hosting.ApplicationModel.IResourceWithEnvironment", - "owningAssembly": "Aspire.Hosting", - "declaration": "export interface ResourceWithEnvironment extends ResourceBuilderBase", - "summary": "Represents a resource that is associated with an environment.", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:ResourceWithEnvironment.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ResourceWithEnvironmentPromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "ResourceWithEnvironmentPromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:ResourceWithEnvironment.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ResourceWithEnvironmentPromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "ResourceWithEnvironmentPromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - } - ] - }, - { - "id": "dto:TestConfigDto", - "kind": "dto", - "name": "TestConfigDto", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestConfigDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestConfigDto", - "summary": "Test DTO to verify [AspireDto] generates TypeScript interfaces.", - "members": [ - { - "id": "property:TestConfigDto.name", - "kind": "property", - "name": "name", - "declaration": "name?: string", - "summary": "The name of the test config." - }, - { - "id": "property:TestConfigDto.port", - "kind": "property", - "name": "port", - "declaration": "port?: number", - "summary": "The port used by the test config." - }, - { - "id": "property:TestConfigDto.enabled", - "kind": "property", - "name": "enabled", - "declaration": "enabled?: boolean", - "summary": "A value indicating whether the test config is enabled." - }, - { - "id": "property:TestConfigDto.optionalField", - "kind": "property", - "name": "optionalField", - "declaration": "optionalField?: string | null", - "summary": "An optional test config field." - } - ] - }, - { - "id": "dto:TestDeeplyNestedDto", - "kind": "dto", - "name": "TestDeeplyNestedDto", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestDeeplyNestedDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestDeeplyNestedDto", - "summary": "Test DTO with deeply nested generic types.", - "members": [ - { - "id": "property:TestDeeplyNestedDto.nestedData", - "kind": "property", - "name": "nestedData", - "declaration": "nestedData?: Record\u003Cstring, TestConfigDto[]\u003E", - "summary": "Deeply nested generic: Dictionary containing List of DTOs." - }, - { - "id": "property:TestDeeplyNestedDto.metadataArray", - "kind": "property", - "name": "metadataArray", - "declaration": "metadataArray?: Record\u003Cstring, string\u003E[]", - "summary": "Array of dictionaries." - } - ] - }, - { - "id": "dto:TestNestedDto", - "kind": "dto", - "name": "TestNestedDto", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestNestedDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestNestedDto", - "summary": "Test DTO with complex nested types.", - "members": [ - { - "id": "property:TestNestedDto.id", - "kind": "property", - "name": "id", - "declaration": "id?: string" - }, - { - "id": "property:TestNestedDto.config", - "kind": "property", - "name": "config", - "declaration": "config?: TestConfigDto" - }, - { - "id": "property:TestNestedDto.tags", - "kind": "property", - "name": "tags", - "declaration": "tags?: string[]" - }, - { - "id": "property:TestNestedDto.counts", - "kind": "property", - "name": "counts", - "declaration": "counts?: Record\u003Cstring, number\u003E" - } - ] - }, - { - "id": "enum:TestPersistenceMode", - "kind": "enum", - "name": "TestPersistenceMode", - "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestPersistenceMode", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export enum TestPersistenceMode", - "summary": "Test persistence mode enum.", - "members": [ - { - "id": "enumValue:TestPersistenceMode.None", - "kind": "property", - "name": "None", - "declaration": "None = \u0022None\u0022" - }, - { - "id": "enumValue:TestPersistenceMode.Volume", - "kind": "property", - "name": "Volume", - "declaration": "Volume = \u0022Volume\u0022" - }, - { - "id": "enumValue:TestPersistenceMode.Bind", - "kind": "property", - "name": "Bind", - "declaration": "Bind = \u0022Bind\u0022" - } - ] - }, - { - "id": "enum:TestResourceStatus", - "kind": "enum", - "name": "TestResourceStatus", - "typeId": "enum:Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestResourceStatus", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export enum TestResourceStatus", - "summary": "Test enum for type generation verification.", - "members": [ - { - "id": "enumValue:TestResourceStatus.Pending", - "kind": "property", - "name": "Pending", - "declaration": "Pending = \u0022Pending\u0022", - "summary": "The resource is pending." - }, - { - "id": "enumValue:TestResourceStatus.Running", - "kind": "property", - "name": "Running", - "declaration": "Running = \u0022Running\u0022", - "summary": "The resource is running." - }, - { - "id": "enumValue:TestResourceStatus.Stopped", - "kind": "property", - "name": "Stopped", - "declaration": "Stopped = \u0022Stopped\u0022", - "summary": "The resource is stopped." - }, - { - "id": "enumValue:TestResourceStatus.Failed", - "kind": "property", - "name": "Failed", - "declaration": "Failed = \u0022Failed\u0022", - "summary": "The resource failed." - } - ] - }, - { - "id": "interface:TestCallbackContext", - "kind": "interface", - "name": "TestCallbackContext", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestCallbackContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestCallbackContext", - "summary": "Test callback context for WithCustomCallback. Also used to verify [AspireExport(ExposeProperties = true)] scanning.", - "members": [ - { - "id": "property:TestCallbackContext.name", - "kind": "property", - "name": "name", - "declaration": "name: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCallbackContext.name" - }, - { - "id": "property:TestCallbackContext.value", - "kind": "property", - "name": "value", - "declaration": "value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCallbackContext.value" - }, - { - "id": "property:TestCallbackContext.cancellationToken", - "kind": "property", - "name": "cancellationToken", - "declaration": "cancellationToken: { get: () =\u003E Promise\u003CCancellationToken\u003E; set: (value: AbortSignal | CancellationToken) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCallbackContext.cancellationToken", - "summary": "CancellationToken is supported by ATS." - } - ] - }, - { - "id": "interface:TestCollectionContext", - "kind": "interface", - "name": "TestCollectionContext", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestCollectionContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestCollectionContext", - "summary": "Test context with collection properties to verify consistent code generation. Verifies both List and Dictionary properties generate proper getter patterns.", - "members": [ - { - "id": "property:TestCollectionContext.items", - "kind": "property", - "name": "items", - "declaration": "items(): Promise\u003CAspireList\u003Cstring\u003E\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCollectionContext.items", - "summary": "List property - should generate AspireList getter like Dictionary properties." - }, - { - "id": "property:TestCollectionContext.metadata", - "kind": "property", - "name": "metadata", - "declaration": "metadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestCollectionContext.metadata", - "summary": "Dictionary property - already works with AspireDict getter." - } - ] - }, - { - "id": "interface:TestDatabaseResource", - "kind": "interface", - "name": "TestDatabaseResource", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestDatabaseResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestDatabaseResource extends ResourceBuilderBase", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:TestDatabaseResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "TestDatabaseResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:TestDatabaseResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "TestDatabaseResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "TestDatabaseResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "TestDatabaseResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:TestDatabaseResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "TestDatabaseResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "TestDatabaseResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "TestDatabaseResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "TestDatabaseResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "TestDatabaseResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "TestDatabaseResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "TestDatabaseResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "TestDatabaseResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "TestDatabaseResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "TestDatabaseResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:TestDatabaseResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "TestDatabaseResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "interface:TestEnvironmentContext", - "kind": "interface", - "name": "TestEnvironmentContext", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestEnvironmentContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestEnvironmentContext", - "summary": "Test environment context used in callbacks. Verifies property-like object pattern (ctx.name.get(), ctx.name.set()).", - "members": [ - { - "id": "property:TestEnvironmentContext.name", - "kind": "property", - "name": "name", - "declaration": "name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestEnvironmentContext.name" - }, - { - "id": "property:TestEnvironmentContext.description", - "kind": "property", - "name": "description", - "declaration": "description: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestEnvironmentContext.description" - }, - { - "id": "property:TestEnvironmentContext.priority", - "kind": "property", - "name": "priority", - "declaration": "priority: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestEnvironmentContext.priority" - } - ] - }, - { - "id": "interface:TestMutableCollectionContext", - "kind": "interface", - "name": "TestMutableCollectionContext", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestMutableCollectionContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestMutableCollectionContext", - "members": [ - { - "id": "property:TestMutableCollectionContext.tags", - "kind": "property", - "name": "tags", - "declaration": "readonly tags: AspireList\u003Cstring\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestMutableCollectionContext.tags" - }, - { - "id": "property:TestMutableCollectionContext.counts", - "kind": "property", - "name": "counts", - "declaration": "readonly counts: AspireDict\u003Cstring, number\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestMutableCollectionContext.counts" - } - ] - }, - { - "id": "interface:TestRedisResource", - "kind": "interface", - "name": "TestRedisResource", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestRedisResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestRedisResource extends ResourceBuilderBase", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:TestRedisResource.addTestChildDatabase", - "kind": "method", - "name": "addTestChildDatabase", - "declaration": "addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/addTestChildDatabase", - "returnType": "TestDatabaseResourcePromise", - "summary": "Adds a child database to a test Redis resource", - "remarks": "This method tests the factory method codegen pattern where a method on builder type A\nreturns builder type B (e.g., SqlServerServerResource.AddDatabase returning SqlServerDatabaseResource).", - "parameters": [ - { - "name": "name", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "AddTestChildDatabaseOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withPersistence", - "kind": "method", - "name": "withPersistence", - "declaration": "withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withPersistence", - "returnType": "TestRedisResourcePromise", - "summary": "Configures the Redis resource with persistence", - "parameters": [ - { - "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "TestRedisResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "TestRedisResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.getTags", - "kind": "method", - "name": "getTags", - "declaration": "getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getTags", - "returnType": "Promise\u003CAspireList\u003Cstring\u003E\u003E", - "summary": "Gets the tags for the resource" - }, - { - "id": "method:TestRedisResource.getMetadata", - "kind": "method", - "name": "getMetadata", - "declaration": "getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getMetadata", - "returnType": "Promise\u003CAspireDict\u003Cstring, string\u003E\u003E", - "summary": "Gets the metadata for the resource" - }, - { - "id": "method:TestRedisResource.withConnectionString", - "kind": "method", - "name": "withConnectionString", - "declaration": "withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionString", - "returnType": "TestRedisResourcePromise", - "summary": "Sets the connection string using a reference expression", - "parameters": [ - { - "name": "connectionString", - "type": "ReferenceExpression", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "TestRedisResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "TestRedisResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "TestRedisResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "TestRedisResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "TestRedisResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "TestRedisResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "TestRedisResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "TestRedisResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "TestRedisResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.getEndpoints", - "kind": "method", - "name": "getEndpoints", - "declaration": "getEndpoints(): Promise\u003Cstring[]\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getEndpoints", - "returnType": "Promise\u003Cstring[]\u003E", - "summary": "Gets the endpoints" - }, - { - "id": "method:TestRedisResource.withConnectionStringDirect", - "kind": "method", - "name": "withConnectionStringDirect", - "declaration": "withConnectionStringDirect(connectionString: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConnectionStringDirect", - "returnType": "TestRedisResourcePromise", - "summary": "Sets connection string using direct interface target", - "parameters": [ - { - "name": "connectionString", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withRedisSpecific", - "kind": "method", - "name": "withRedisSpecific", - "declaration": "withRedisSpecific(option: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withRedisSpecific", - "returnType": "TestRedisResourcePromise", - "summary": "Redis-specific configuration", - "parameters": [ - { - "name": "option", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "TestRedisResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "TestRedisResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "TestRedisResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "TestRedisResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.getStatusAsync", - "kind": "method", - "name": "getStatusAsync", - "declaration": "getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/getStatusAsync", - "returnType": "Promise\u003Cstring\u003E", - "summary": "Gets the status of the resource asynchronously", - "parameters": [ - { - "name": "options", - "type": "GetStatusAsyncOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "TestRedisResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.waitForReadyAsync", - "kind": "method", - "name": "waitForReadyAsync", - "declaration": "waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/waitForReadyAsync", - "returnType": "Promise\u003Cboolean\u003E", - "summary": "Waits for the resource to be ready", - "parameters": [ - { - "name": "timeout", - "type": "number", - "optional": false - }, - { - "name": "options", - "type": "WaitForReadyAsyncOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withMultiParamHandleCallback", - "kind": "method", - "name": "withMultiParamHandleCallback", - "declaration": "withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMultiParamHandleCallback", - "returnType": "TestRedisResourcePromise", - "summary": "Tests multi-param callback destructuring", - "parameters": [ - { - "name": "callback", - "type": "(arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withDataVolume", - "kind": "method", - "name": "withDataVolume", - "declaration": "withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDataVolume", - "returnType": "TestRedisResourcePromise", - "summary": "Adds a data volume with persistence", - "parameters": [ - { - "name": "options", - "type": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "TestRedisResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "TestRedisResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "TestRedisResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "TestRedisResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "TestRedisResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "TestRedisResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:TestRedisResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "TestRedisResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:TestRedisResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "TestRedisResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "interface:TestResourceContext", - "kind": "interface", - "name": "TestResourceContext", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestResourceContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestResourceContext", - "summary": "Test context type with exposed instance methods. Verifies [AspireExport(ExposeMethods=true)] generates async methods.", - "members": [ - { - "id": "property:TestResourceContext.name", - "kind": "property", - "name": "name", - "declaration": "name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.name" - }, - { - "id": "property:TestResourceContext.value", - "kind": "property", - "name": "value", - "declaration": "value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E }", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.value" - }, - { - "id": "method:TestResourceContext.getValueAsync", - "kind": "method", - "name": "getValueAsync", - "declaration": "getValueAsync(): Promise\u003Cstring\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.getValueAsync", - "returnType": "Promise\u003Cstring\u003E", - "summary": "Instance method that should be exposed as async method." - }, - { - "id": "method:TestResourceContext.setValueAsync", - "kind": "method", - "name": "setValueAsync", - "declaration": "setValueAsync(value: string): TestResourceContextPromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.setValueAsync", - "returnType": "TestResourceContextPromise", - "summary": "Instance method with parameter.", - "parameters": [ - { - "name": "value", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestResourceContext.validateAsync", - "kind": "method", - "name": "validateAsync", - "declaration": "validateAsync(): Promise\u003Cboolean\u003E", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes/TestResourceContext.validateAsync", - "returnType": "Promise\u003Cboolean\u003E", - "summary": "Instance method with return type." - } - ] - }, - { - "id": "interface:TestVaultResource", - "kind": "interface", - "name": "TestVaultResource", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.TestVaultResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface TestVaultResource extends ResourceBuilderBase", - "extends": [ - "ResourceBuilderBase" - ], - "members": [ - { - "id": "method:TestVaultResource.withOptionalString", - "kind": "method", - "name": "withOptionalString", - "declaration": "withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalString", - "returnType": "TestVaultResourcePromise", - "summary": "Adds an optional string parameter", - "parameters": [ - { - "name": "options", - "type": "WithOptionalStringOptions", - "optional": true - } - ] - }, - { - "id": "method:TestVaultResource.withConfig", - "kind": "method", - "name": "withConfig", - "declaration": "withConfig(config: TestConfigDto): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withConfig", - "returnType": "TestVaultResourcePromise", - "summary": "Configures the resource with a DTO", - "parameters": [ - { - "name": "config", - "type": "TestConfigDto", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.testWithEnvironmentCallback", - "kind": "method", - "name": "testWithEnvironmentCallback", - "declaration": "testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWithEnvironmentCallback", - "returnType": "TestVaultResourcePromise", - "summary": "Configures environment with callback (test version)", - "parameters": [ - { - "name": "callback", - "type": "(arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withCreatedAt", - "kind": "method", - "name": "withCreatedAt", - "declaration": "withCreatedAt(createdAt: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCreatedAt", - "returnType": "TestVaultResourcePromise", - "summary": "Sets the created timestamp", - "parameters": [ - { - "name": "createdAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withModifiedAt", - "kind": "method", - "name": "withModifiedAt", - "declaration": "withModifiedAt(modifiedAt: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withModifiedAt", - "returnType": "TestVaultResourcePromise", - "summary": "Sets the modified timestamp", - "parameters": [ - { - "name": "modifiedAt", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withCorrelationId", - "kind": "method", - "name": "withCorrelationId", - "declaration": "withCorrelationId(correlationId: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCorrelationId", - "returnType": "TestVaultResourcePromise", - "summary": "Sets the correlation ID", - "parameters": [ - { - "name": "correlationId", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withOptionalCallback", - "kind": "method", - "name": "withOptionalCallback", - "declaration": "withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withOptionalCallback", - "returnType": "TestVaultResourcePromise", - "summary": "Configures with optional callback", - "parameters": [ - { - "name": "options", - "type": "WithOptionalCallbackOptions", - "optional": true - } - ] - }, - { - "id": "method:TestVaultResource.withStatus", - "kind": "method", - "name": "withStatus", - "declaration": "withStatus(status: TestResourceStatus): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withStatus", - "returnType": "TestVaultResourcePromise", - "summary": "Sets the resource status", - "parameters": [ - { - "name": "status", - "type": "TestResourceStatus", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withNestedConfig", - "kind": "method", - "name": "withNestedConfig", - "declaration": "withNestedConfig(config: TestNestedDto): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withNestedConfig", - "returnType": "TestVaultResourcePromise", - "summary": "Configures with nested DTO", - "parameters": [ - { - "name": "config", - "type": "TestNestedDto", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withValidator", - "kind": "method", - "name": "withValidator", - "declaration": "withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withValidator", - "returnType": "TestVaultResourcePromise", - "summary": "Adds validation callback", - "parameters": [ - { - "name": "validator", - "type": "(arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.testWaitFor", - "kind": "method", - "name": "testWaitFor", - "declaration": "testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/testWaitFor", - "returnType": "TestVaultResourcePromise", - "summary": "Waits for another resource (test version)", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withDependency", - "kind": "method", - "name": "withDependency", - "declaration": "withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withDependency", - "returnType": "TestVaultResourcePromise", - "summary": "Adds a dependency on another resource", - "parameters": [ - { - "name": "dependency", - "type": "Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withUnionDependency", - "kind": "method", - "name": "withUnionDependency", - "declaration": "withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withUnionDependency", - "returnType": "TestVaultResourcePromise", - "summary": "Adds a dependency from a string or another resource", - "parameters": [ - { - "name": "dependency", - "type": "string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withEndpoints", - "kind": "method", - "name": "withEndpoints", - "declaration": "withEndpoints(endpoints: string[]): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEndpoints", - "returnType": "TestVaultResourcePromise", - "summary": "Sets the endpoints", - "parameters": [ - { - "name": "endpoints", - "type": "string[]", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withEnvironmentVariables", - "kind": "method", - "name": "withEnvironmentVariables", - "declaration": "withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withEnvironmentVariables", - "returnType": "TestVaultResourcePromise", - "summary": "Sets environment variables", - "parameters": [ - { - "name": "variables", - "type": "Record\u003Cstring, string\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withCancellableOperation", - "kind": "method", - "name": "withCancellableOperation", - "declaration": "withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withCancellableOperation", - "returnType": "TestVaultResourcePromise", - "summary": "Performs a cancellable operation", - "parameters": [ - { - "name": "operation", - "type": "(arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withVaultDirect", - "kind": "method", - "name": "withVaultDirect", - "declaration": "withVaultDirect(option: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withVaultDirect", - "returnType": "TestVaultResourcePromise", - "summary": "Configures vault using direct interface target", - "parameters": [ - { - "name": "option", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withMergeLabel", - "kind": "method", - "name": "withMergeLabel", - "declaration": "withMergeLabel(label: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabel", - "returnType": "TestVaultResourcePromise", - "summary": "Adds a label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withMergeLabelCategorized", - "kind": "method", - "name": "withMergeLabelCategorized", - "declaration": "withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLabelCategorized", - "returnType": "TestVaultResourcePromise", - "summary": "Adds a categorized label to the resource", - "parameters": [ - { - "name": "label", - "type": "string", - "optional": false - }, - { - "name": "category", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withMergeEndpoint", - "kind": "method", - "name": "withMergeEndpoint", - "declaration": "withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpoint", - "returnType": "TestVaultResourcePromise", - "summary": "Configures a named endpoint", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withMergeEndpointScheme", - "kind": "method", - "name": "withMergeEndpointScheme", - "declaration": "withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeEndpointScheme", - "returnType": "TestVaultResourcePromise", - "summary": "Configures a named endpoint with scheme", - "parameters": [ - { - "name": "endpointName", - "type": "string", - "optional": false - }, - { - "name": "port", - "type": "number", - "optional": false - }, - { - "name": "scheme", - "type": "string", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withMergeLogging", - "kind": "method", - "name": "withMergeLogging", - "declaration": "withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLogging", - "returnType": "TestVaultResourcePromise", - "summary": "Configures resource logging", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingOptions", - "optional": true - } - ] - }, - { - "id": "method:TestVaultResource.withMergeLoggingPath", - "kind": "method", - "name": "withMergeLoggingPath", - "declaration": "withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeLoggingPath", - "returnType": "TestVaultResourcePromise", - "summary": "Configures resource logging with file path", - "parameters": [ - { - "name": "logLevel", - "type": "string", - "optional": false - }, - { - "name": "logPath", - "type": "string", - "optional": false - }, - { - "name": "options", - "type": "WithMergeLoggingPathOptions", - "optional": true - } - ] - }, - { - "id": "method:TestVaultResource.withMergeRoute", - "kind": "method", - "name": "withMergeRoute", - "declaration": "withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRoute", - "returnType": "TestVaultResourcePromise", - "summary": "Configures a route", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - } - ] - }, - { - "id": "method:TestVaultResource.withMergeRouteMiddleware", - "kind": "method", - "name": "withMergeRouteMiddleware", - "declaration": "withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise", - "capabilityId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/withMergeRouteMiddleware", - "returnType": "TestVaultResourcePromise", - "summary": "Configures a route with middleware", - "parameters": [ - { - "name": "path", - "type": "string", - "optional": false - }, - { - "name": "method", - "type": "string", - "optional": false - }, - { - "name": "handler", - "type": "string", - "optional": false - }, - { - "name": "priority", - "type": "number", - "optional": false - }, - { - "name": "middleware", - "type": "string", - "optional": false - } - ] - } - ] - }, - { - "id": "options:AddTestChildDatabaseOptions", - "kind": "options", - "name": "AddTestChildDatabaseOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestChildDatabaseOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface AddTestChildDatabaseOptions", - "members": [ - { - "id": "property:AddTestChildDatabaseOptions.databaseName", - "kind": "property", - "name": "databaseName", - "declaration": "databaseName?: string" - } - ] - }, - { - "id": "options:AddTestRedisOptions", - "kind": "options", - "name": "AddTestRedisOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/AddTestRedisOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface AddTestRedisOptions", - "members": [ - { - "id": "property:AddTestRedisOptions.port", - "kind": "property", - "name": "port", - "declaration": "port?: number" - } - ] - }, - { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", - "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", - "members": [ - { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions.name", - "kind": "property", - "name": "name", - "declaration": "name?: string" - }, - { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions.isReadOnly", - "kind": "property", - "name": "isReadOnly", - "declaration": "isReadOnly?: boolean" - } - ] - }, - { - "id": "options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", - "kind": "options", - "name": "Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", - "members": [ - { - "id": "property:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions.mode", - "kind": "property", - "name": "mode", - "declaration": "mode?: TestPersistenceMode" - } - ] - }, - { - "id": "options:GetStatusAsyncOptions", - "kind": "options", - "name": "GetStatusAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/GetStatusAsyncOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface GetStatusAsyncOptions", - "members": [ - { - "id": "property:GetStatusAsyncOptions.cancellationToken", - "kind": "property", - "name": "cancellationToken", - "declaration": "cancellationToken?: AbortSignal | CancellationToken" - } - ] - }, - { - "id": "options:WaitForReadyAsyncOptions", - "kind": "options", - "name": "WaitForReadyAsyncOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WaitForReadyAsyncOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WaitForReadyAsyncOptions", - "members": [ - { - "id": "property:WaitForReadyAsyncOptions.cancellationToken", - "kind": "property", - "name": "cancellationToken", - "declaration": "cancellationToken?: AbortSignal | CancellationToken" - } - ] - }, - { - "id": "options:WithMergeLoggingOptions", - "kind": "options", - "name": "WithMergeLoggingOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithMergeLoggingOptions", - "members": [ - { - "id": "property:WithMergeLoggingOptions.enableConsole", - "kind": "property", - "name": "enableConsole", - "declaration": "enableConsole?: boolean" - }, - { - "id": "property:WithMergeLoggingOptions.maxFiles", - "kind": "property", - "name": "maxFiles", - "declaration": "maxFiles?: number" - } - ] - }, - { - "id": "options:WithMergeLoggingPathOptions", - "kind": "options", - "name": "WithMergeLoggingPathOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithMergeLoggingPathOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithMergeLoggingPathOptions", - "members": [ - { - "id": "property:WithMergeLoggingPathOptions.enableConsole", - "kind": "property", - "name": "enableConsole", - "declaration": "enableConsole?: boolean" - }, - { - "id": "property:WithMergeLoggingPathOptions.maxFiles", - "kind": "property", - "name": "maxFiles", - "declaration": "maxFiles?: number" - } - ] - }, - { - "id": "options:WithOptionalCallbackOptions", - "kind": "options", - "name": "WithOptionalCallbackOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalCallbackOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithOptionalCallbackOptions", - "members": [ - { - "id": "property:WithOptionalCallbackOptions.callback", - "kind": "property", - "name": "callback", - "declaration": "callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E" - } - ] - }, - { - "id": "options:WithOptionalStringOptions", - "kind": "options", - "name": "WithOptionalStringOptions", - "typeId": "Aspire.Hosting.CodeGeneration.TypeScript.Tests/WithOptionalStringOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "declaration": "export interface WithOptionalStringOptions", - "members": [ - { - "id": "property:WithOptionalStringOptions.value", - "kind": "property", - "name": "value", - "declaration": "value?: string" - }, - { - "id": "property:WithOptionalStringOptions.enabled", - "kind": "property", - "name": "enabled", - "declaration": "enabled?: boolean" - } - ] - } - ] - } - ], - "declarations": [ - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResource {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:CSharpAppResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface CSharpAppResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): CSharpAppResourcePromise;\n withConfig(config: TestConfigDto): CSharpAppResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withCreatedAt(createdAt: string): CSharpAppResourcePromise;\n withModifiedAt(modifiedAt: string): CSharpAppResourcePromise;\n withCorrelationId(correlationId: string): CSharpAppResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): CSharpAppResourcePromise;\n withStatus(status: TestResourceStatus): CSharpAppResourcePromise;\n withNestedConfig(config: TestNestedDto): CSharpAppResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): CSharpAppResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): CSharpAppResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): CSharpAppResourcePromise;\n withEndpoints(endpoints: string[]): CSharpAppResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): CSharpAppResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): CSharpAppResourcePromise;\n withMergeLabel(label: string): CSharpAppResourcePromise;\n withMergeLabelCategorized(label: string, category: string): CSharpAppResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): CSharpAppResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): CSharpAppResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): CSharpAppResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): CSharpAppResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): CSharpAppResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): CSharpAppResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerRegistryResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerRegistryResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerRegistryResourcePromise;\n withConfig(config: TestConfigDto): ContainerRegistryResourcePromise;\n withCreatedAt(createdAt: string): ContainerRegistryResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerRegistryResourcePromise;\n withCorrelationId(correlationId: string): ContainerRegistryResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerRegistryResourcePromise;\n withStatus(status: TestResourceStatus): ContainerRegistryResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerRegistryResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerRegistryResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerRegistryResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerRegistryResourcePromise;\n withEndpoints(endpoints: string[]): ContainerRegistryResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerRegistryResourcePromise;\n withMergeLabel(label: string): ContainerRegistryResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerRegistryResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerRegistryResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerRegistryResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerRegistryResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerRegistryResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerRegistryResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerRegistryResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResource {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ContainerResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ContainerResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ContainerResourcePromise;\n withConfig(config: TestConfigDto): ContainerResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withCreatedAt(createdAt: string): ContainerResourcePromise;\n withModifiedAt(modifiedAt: string): ContainerResourcePromise;\n withCorrelationId(correlationId: string): ContainerResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ContainerResourcePromise;\n withStatus(status: TestResourceStatus): ContainerResourcePromise;\n withNestedConfig(config: TestNestedDto): ContainerResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ContainerResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ContainerResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ContainerResourcePromise;\n withEndpoints(endpoints: string[]): ContainerResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ContainerResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ContainerResourcePromise;\n withMergeLabel(label: string): ContainerResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ContainerResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ContainerResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ContainerResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ContainerResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ContainerResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ContainerResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ContainerResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilder", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilder {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DistributedApplicationBuilderPromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DistributedApplicationBuilderPromise {\n addTestRedis(name: string, options?: AddTestRedisOptions): TestRedisResourcePromise;\n addTestVault(name: string): TestVaultResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResource {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:DotnetToolResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface DotnetToolResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): DotnetToolResourcePromise;\n withConfig(config: TestConfigDto): DotnetToolResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withCreatedAt(createdAt: string): DotnetToolResourcePromise;\n withModifiedAt(modifiedAt: string): DotnetToolResourcePromise;\n withCorrelationId(correlationId: string): DotnetToolResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): DotnetToolResourcePromise;\n withStatus(status: TestResourceStatus): DotnetToolResourcePromise;\n withNestedConfig(config: TestNestedDto): DotnetToolResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): DotnetToolResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): DotnetToolResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): DotnetToolResourcePromise;\n withEndpoints(endpoints: string[]): DotnetToolResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): DotnetToolResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): DotnetToolResourcePromise;\n withMergeLabel(label: string): DotnetToolResourcePromise;\n withMergeLabelCategorized(label: string, category: string): DotnetToolResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): DotnetToolResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): DotnetToolResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): DotnetToolResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): DotnetToolResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): DotnetToolResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): DotnetToolResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResource {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExecutableResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExecutableResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExecutableResourcePromise;\n withConfig(config: TestConfigDto): ExecutableResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withCreatedAt(createdAt: string): ExecutableResourcePromise;\n withModifiedAt(modifiedAt: string): ExecutableResourcePromise;\n withCorrelationId(correlationId: string): ExecutableResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExecutableResourcePromise;\n withStatus(status: TestResourceStatus): ExecutableResourcePromise;\n withNestedConfig(config: TestNestedDto): ExecutableResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExecutableResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExecutableResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExecutableResourcePromise;\n withEndpoints(endpoints: string[]): ExecutableResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ExecutableResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExecutableResourcePromise;\n withMergeLabel(label: string): ExecutableResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExecutableResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExecutableResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExecutableResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExecutableResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExecutableResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExecutableResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExecutableResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResource {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ExternalServiceResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ExternalServiceResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ExternalServiceResourcePromise;\n withConfig(config: TestConfigDto): ExternalServiceResourcePromise;\n withCreatedAt(createdAt: string): ExternalServiceResourcePromise;\n withModifiedAt(modifiedAt: string): ExternalServiceResourcePromise;\n withCorrelationId(correlationId: string): ExternalServiceResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ExternalServiceResourcePromise;\n withStatus(status: TestResourceStatus): ExternalServiceResourcePromise;\n withNestedConfig(config: TestNestedDto): ExternalServiceResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ExternalServiceResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ExternalServiceResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ExternalServiceResourcePromise;\n withEndpoints(endpoints: string[]): ExternalServiceResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ExternalServiceResourcePromise;\n withMergeLabel(label: string): ExternalServiceResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ExternalServiceResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ExternalServiceResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ExternalServiceResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ExternalServiceResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ExternalServiceResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ExternalServiceResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ExternalServiceResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResource {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ParameterResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ParameterResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ParameterResourcePromise;\n withConfig(config: TestConfigDto): ParameterResourcePromise;\n withCreatedAt(createdAt: string): ParameterResourcePromise;\n withModifiedAt(modifiedAt: string): ParameterResourcePromise;\n withCorrelationId(correlationId: string): ParameterResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ParameterResourcePromise;\n withStatus(status: TestResourceStatus): ParameterResourcePromise;\n withNestedConfig(config: TestNestedDto): ParameterResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ParameterResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ParameterResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ParameterResourcePromise;\n withEndpoints(endpoints: string[]): ParameterResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ParameterResourcePromise;\n withMergeLabel(label: string): ParameterResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ParameterResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ParameterResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ParameterResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ParameterResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ParameterResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ParameterResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ParameterResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResource {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ProjectResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ProjectResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ProjectResourcePromise;\n withConfig(config: TestConfigDto): ProjectResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withCreatedAt(createdAt: string): ProjectResourcePromise;\n withModifiedAt(modifiedAt: string): ProjectResourcePromise;\n withCorrelationId(correlationId: string): ProjectResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ProjectResourcePromise;\n withStatus(status: TestResourceStatus): ProjectResourcePromise;\n withNestedConfig(config: TestNestedDto): ProjectResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ProjectResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ProjectResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ProjectResourcePromise;\n withEndpoints(endpoints: string[]): ProjectResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ProjectResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ProjectResourcePromise;\n withMergeLabel(label: string): ProjectResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ProjectResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ProjectResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ProjectResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ProjectResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ProjectResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ProjectResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ProjectResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:Resource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Resource {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourcePromise {\n withOptionalString(options?: WithOptionalStringOptions): ResourcePromise;\n withConfig(config: TestConfigDto): ResourcePromise;\n withCreatedAt(createdAt: string): ResourcePromise;\n withModifiedAt(modifiedAt: string): ResourcePromise;\n withCorrelationId(correlationId: string): ResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): ResourcePromise;\n withStatus(status: TestResourceStatus): ResourcePromise;\n withNestedConfig(config: TestNestedDto): ResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): ResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): ResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): ResourcePromise;\n withEndpoints(endpoints: string[]): ResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): ResourcePromise;\n withMergeLabel(label: string): ResourcePromise;\n withMergeLabelCategorized(label: string, category: string): ResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): ResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): ResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): ResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): ResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): ResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): ResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionString", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourceWithConnectionString {\n withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise;\n withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithConnectionStringPromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourceWithConnectionStringPromise {\n withConnectionString(connectionString: ReferenceExpression): ResourceWithConnectionStringPromise;\n withConnectionStringDirect(connectionString: string): ResourceWithConnectionStringPromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironment", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourceWithEnvironment {\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ResourceWithEnvironmentPromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ResourceWithEnvironmentPromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:augment:ResourceWithEnvironmentPromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface ResourceWithEnvironmentPromise {\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): ResourceWithEnvironmentPromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): ResourceWithEnvironmentPromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestConfigDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestConfigDto {\n name?: string;\n port?: number;\n enabled?: boolean;\n optionalField?: string | null;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestDeeplyNestedDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDeeplyNestedDto {\n nestedData?: Record\u003Cstring, TestConfigDto[]\u003E;\n metadataArray?: Record\u003Cstring, string\u003E[];\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:dto:TestNestedDto", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestNestedDto {\n id?: string;\n config?: TestConfigDto;\n tags?: string[];\n counts?: Record\u003Cstring, number\u003E;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestPersistenceMode", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export enum TestPersistenceMode {\n None = \u0022None\u0022,\n Volume = \u0022Volume\u0022,\n Bind = \u0022Bind\u0022,\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:enum:TestResourceStatus", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export enum TestResourceStatus {\n Pending = \u0022Pending\u0022,\n Running = \u0022Running\u0022,\n Stopped = \u0022Stopped\u0022,\n Failed = \u0022Failed\u0022,\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:handle:ITestVaultResourceHandle", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export type ITestVaultResourceHandle = Handle\u003C\u0027Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.TestTypes.ITestVaultResource\u0027\u003E;" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCallbackContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestCallbackContext {\n toJSON(): MarshalledHandle;\n name: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E };\n value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n cancellationToken: { get: () =\u003E Promise\u003CCancellationToken\u003E; set: (value: AbortSignal | CancellationToken) =\u003E Promise\u003Cvoid\u003E };\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestCollectionContext {\n toJSON(): MarshalledHandle;\n items(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n metadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestCollectionContextPromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestCollectionContextPromise extends PromiseLike\u003CTestCollectionContext\u003E {\n items(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n metadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestDatabaseResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestDatabaseResourcePromise extends PromiseLike\u003CTestDatabaseResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestDatabaseResourcePromise;\n withConfig(config: TestConfigDto): TestDatabaseResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withCreatedAt(createdAt: string): TestDatabaseResourcePromise;\n withModifiedAt(modifiedAt: string): TestDatabaseResourcePromise;\n withCorrelationId(correlationId: string): TestDatabaseResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestDatabaseResourcePromise;\n withStatus(status: TestResourceStatus): TestDatabaseResourcePromise;\n withNestedConfig(config: TestNestedDto): TestDatabaseResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestDatabaseResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestDatabaseResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestDatabaseResourcePromise;\n withEndpoints(endpoints: string[]): TestDatabaseResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestDatabaseResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestDatabaseResourcePromise;\n withMergeLabel(label: string): TestDatabaseResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestDatabaseResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestDatabaseResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestDatabaseResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestDatabaseResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestDatabaseResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestDatabaseResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestDatabaseResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestEnvironmentContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestEnvironmentContext {\n toJSON(): MarshalledHandle;\n name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E };\n description: { get: () =\u003E Promise\u003Cstring | null\u003E; set: (value: string | null) =\u003E Promise\u003Cvoid\u003E };\n priority: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestMutableCollectionContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestMutableCollectionContext {\n toJSON(): MarshalledHandle;\n readonly tags: AspireList\u003Cstring\u003E;\n readonly counts: AspireDict\u003Cstring, number\u003E;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestRedisResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestRedisResourcePromise extends PromiseLike\u003CTestRedisResource\u003E {\n addTestChildDatabase(name: string, options?: AddTestChildDatabaseOptions): TestDatabaseResourcePromise;\n withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise;\n withOptionalString(options?: WithOptionalStringOptions): TestRedisResourcePromise;\n withConfig(config: TestConfigDto): TestRedisResourcePromise;\n getTags(): Promise\u003CAspireList\u003Cstring\u003E\u003E;\n getMetadata(): Promise\u003CAspireDict\u003Cstring, string\u003E\u003E;\n withConnectionString(connectionString: ReferenceExpression): TestRedisResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withCreatedAt(createdAt: string): TestRedisResourcePromise;\n withModifiedAt(modifiedAt: string): TestRedisResourcePromise;\n withCorrelationId(correlationId: string): TestRedisResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestRedisResourcePromise;\n withStatus(status: TestResourceStatus): TestRedisResourcePromise;\n withNestedConfig(config: TestNestedDto): TestRedisResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestRedisResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestRedisResourcePromise;\n getEndpoints(): Promise\u003Cstring[]\u003E;\n withConnectionStringDirect(connectionString: string): TestRedisResourcePromise;\n withRedisSpecific(option: string): TestRedisResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestRedisResourcePromise;\n withEndpoints(endpoints: string[]): TestRedisResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestRedisResourcePromise;\n getStatusAsync(options?: GetStatusAsyncOptions): Promise\u003Cstring\u003E;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n waitForReadyAsync(timeout: number, options?: WaitForReadyAsyncOptions): Promise\u003Cboolean\u003E;\n withMultiParamHandleCallback(callback: (arg1: TestCallbackContext, arg2: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestRedisResourcePromise;\n withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise;\n withMergeLabel(label: string): TestRedisResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestRedisResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestRedisResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestRedisResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestRedisResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestRedisResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestRedisResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestRedisResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContext", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestResourceContext {\n toJSON(): MarshalledHandle;\n name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E };\n value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n getValueAsync(): Promise\u003Cstring\u003E;\n setValueAsync(value: string): TestResourceContextPromise;\n validateAsync(): Promise\u003Cboolean\u003E;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestResourceContextPromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestResourceContextPromise extends PromiseLike\u003CTestResourceContext\u003E {\n name: { get: () =\u003E Promise\u003Cstring\u003E; set: (value: string) =\u003E Promise\u003Cvoid\u003E };\n value: { get: () =\u003E Promise\u003Cnumber\u003E; set: (value: number) =\u003E Promise\u003Cvoid\u003E };\n getValueAsync(): Promise\u003Cstring\u003E;\n setValueAsync(value: string): TestResourceContextPromise;\n validateAsync(): Promise\u003Cboolean\u003E;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResource", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResource extends ResourceBuilderBase {\n toJSON(): MarshalledHandle;\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:interface:TestVaultResourcePromise", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface TestVaultResourcePromise extends PromiseLike\u003CTestVaultResource\u003E {\n withOptionalString(options?: WithOptionalStringOptions): TestVaultResourcePromise;\n withConfig(config: TestConfigDto): TestVaultResourcePromise;\n testWithEnvironmentCallback(callback: (arg: TestEnvironmentContext) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withCreatedAt(createdAt: string): TestVaultResourcePromise;\n withModifiedAt(modifiedAt: string): TestVaultResourcePromise;\n withCorrelationId(correlationId: string): TestVaultResourcePromise;\n withOptionalCallback(options?: WithOptionalCallbackOptions): TestVaultResourcePromise;\n withStatus(status: TestResourceStatus): TestVaultResourcePromise;\n withNestedConfig(config: TestNestedDto): TestVaultResourcePromise;\n withValidator(validator: (arg: TestResourceContext) =\u003E Promise\u003Cboolean\u003E): TestVaultResourcePromise;\n testWaitFor(dependency: Awaitable\u003CCSharpAppResource | ContainerRegistryResource | ContainerResource | DotnetToolResource | ExecutableResource | ExternalServiceResource | ParameterResource | ProjectResource | Resource | ResourceWithArgs | ResourceWithConnectionString | ResourceWithEndpoints | ResourceWithEnvironment | ResourceWithWaitSupport | TestDatabaseResource | TestRedisResource | TestVaultResource\u003E): TestVaultResourcePromise;\n withDependency(dependency: Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withUnionDependency(dependency: string | ResourceWithConnectionString | TestRedisResource | Awaitable\u003CResourceWithConnectionString | TestRedisResource\u003E): TestVaultResourcePromise;\n withEndpoints(endpoints: string[]): TestVaultResourcePromise;\n withEnvironmentVariables(variables: Record\u003Cstring, string\u003E): TestVaultResourcePromise;\n withCancellableOperation(operation: (arg: CancellationToken) =\u003E Promise\u003Cvoid\u003E): TestVaultResourcePromise;\n withVaultDirect(option: string): TestVaultResourcePromise;\n withMergeLabel(label: string): TestVaultResourcePromise;\n withMergeLabelCategorized(label: string, category: string): TestVaultResourcePromise;\n withMergeEndpoint(endpointName: string, port: number): TestVaultResourcePromise;\n withMergeEndpointScheme(endpointName: string, port: number, scheme: string): TestVaultResourcePromise;\n withMergeLogging(logLevel: string, options?: WithMergeLoggingOptions): TestVaultResourcePromise;\n withMergeLoggingPath(logLevel: string, logPath: string, options?: WithMergeLoggingPathOptions): TestVaultResourcePromise;\n withMergeRoute(path: string, method: string, handler: string, priority: number): TestVaultResourcePromise;\n withMergeRouteMiddleware(path: string, method: string, handler: string, priority: number, middleware: string): TestVaultResourcePromise;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestChildDatabaseOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface AddTestChildDatabaseOptions {\n databaseName?: string;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:AddTestRedisOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface AddTestRedisOptions {\n port?: number;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions {\n name?: string;\n isReadOnly?: boolean;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions {\n mode?: TestPersistenceMode;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:GetStatusAsyncOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface GetStatusAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WaitForReadyAsyncOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WaitForReadyAsyncOptions {\n cancellationToken?: AbortSignal | CancellationToken;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithMergeLoggingOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithMergeLoggingPathOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithMergeLoggingPathOptions {\n enableConsole?: boolean;\n maxFiles?: number;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalCallbackOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithOptionalCallbackOptions {\n callback?: (arg: TestCallbackContext) =\u003E Promise\u003Cvoid\u003E;\n}" - }, - { - "id": "Aspire.Hosting.CodeGeneration.TypeScript.Tests:options:WithOptionalStringOptions", - "owningAssembly": "Aspire.Hosting.CodeGeneration.TypeScript.Tests", - "content": "export interface WithOptionalStringOptions {\n value?: string;\n enabled?: boolean;\n}" - }, - { - "id": "Aspire.Hosting:handle:CommandLineArgsCallbackContextHandle", - "owningAssembly": "Aspire.Hosting", - "content": "export type CommandLineArgsCallbackContextHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.CommandLineArgsCallbackContext\u0027\u003E;" - }, - { - "id": "Aspire.Hosting:handle:EndpointReferenceHandle", - "owningAssembly": "Aspire.Hosting", - "content": "export type EndpointReferenceHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointReference\u0027\u003E;" - }, - { - "id": "Aspire.Hosting:handle:EndpointUpdateContextHandle", - "owningAssembly": "Aspire.Hosting", - "content": "export type EndpointUpdateContextHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.EndpointUpdateContext\u0027\u003E;" - }, - { - "id": "Aspire.Hosting:handle:ReferenceExpressionHandle", - "owningAssembly": "Aspire.Hosting", - "content": "export type ReferenceExpressionHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.ReferenceExpression\u0027\u003E;" - }, - { - "id": "Aspire.Hosting:handle:ResourceEndpointsAllocatedEventHandle", - "owningAssembly": "Aspire.Hosting", - "content": "export type ResourceEndpointsAllocatedEventHandle = Handle\u003C\u0027Aspire.Hosting/Aspire.Hosting.ApplicationModel.ResourceEndpointsAllocatedEvent\u0027\u003E;" - }, - { - "id": "Aspire.Hosting:opaque:CSharpAppResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface CSharpAppResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:CSharpAppResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface CSharpAppResourcePromise extends PromiseLike\u003CCSharpAppResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ContainerRegistryResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ContainerRegistryResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ContainerRegistryResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ContainerRegistryResourcePromise extends PromiseLike\u003CContainerRegistryResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ContainerResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ContainerResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ContainerResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ContainerResourcePromise extends PromiseLike\u003CContainerResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:DistributedApplicationBuilder", - "owningAssembly": "Aspire.Hosting", - "content": "export interface DistributedApplicationBuilder extends HandleReference {}" - }, - { - "id": "Aspire.Hosting:opaque:DistributedApplicationBuilderPromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface DistributedApplicationBuilderPromise extends PromiseLike\u003CDistributedApplicationBuilder\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:DotnetToolResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface DotnetToolResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:DotnetToolResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface DotnetToolResourcePromise extends PromiseLike\u003CDotnetToolResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ExecutableResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ExecutableResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ExecutableResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ExecutableResourcePromise extends PromiseLike\u003CExecutableResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ExternalServiceResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ExternalServiceResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ExternalServiceResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ExternalServiceResourcePromise extends PromiseLike\u003CExternalServiceResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ParameterResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ParameterResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ParameterResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ParameterResourcePromise extends PromiseLike\u003CParameterResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ProjectResource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ProjectResource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ProjectResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ProjectResourcePromise extends PromiseLike\u003CProjectResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:Resource", - "owningAssembly": "Aspire.Hosting", - "content": "export interface Resource extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourcePromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourcePromise extends PromiseLike\u003CResource\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithArgs", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithArgs extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithArgsPromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithArgsPromise extends PromiseLike\u003CResourceWithArgs\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithConnectionString", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithConnectionString extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithConnectionStringPromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithConnectionStringPromise extends PromiseLike\u003CResourceWithConnectionString\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithEndpoints", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithEndpoints extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithEndpointsPromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithEndpointsPromise extends PromiseLike\u003CResourceWithEndpoints\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithEnvironment", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithEnvironment extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithEnvironmentPromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithEnvironmentPromise extends PromiseLike\u003CResourceWithEnvironment\u003E {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithWaitSupport", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithWaitSupport extends ResourceBuilderBase {}" - }, - { - "id": "Aspire.Hosting:opaque:ResourceWithWaitSupportPromise", - "owningAssembly": "Aspire.Hosting", - "content": "export interface ResourceWithWaitSupportPromise extends PromiseLike\u003CResourceWithWaitSupport\u003E {}" - }, - { - "id": "aspire:runtime:base", - "owningAssembly": "Aspire.Hosting", - "content": "export type Awaitable\u003CT\u003E = T | PromiseLike\u003CT\u003E;\nexport interface MarshalledHandle { $handle: string; $type: string; }\nexport interface Handle\u003CT extends string = string\u003E { readonly $handle: string; readonly $type: T; toJSON(): MarshalledHandle; }\nexport interface HandleReference { toJSON(): MarshalledHandle; }\nexport interface AbortSignal { readonly aborted: boolean; }\nexport interface CancellationToken { readonly aborted: boolean; }\nexport enum InputType { Text = \u0027Text\u0027, SecretText = \u0027SecretText\u0027, Choice = \u0027Choice\u0027, Boolean = \u0027Boolean\u0027, Number = \u0027Number\u0027 }\nexport interface ReferenceExpression { readonly value: Promise\u003Cstring\u003E; }\nexport interface AspireList\u003CT\u003E extends HandleReference { get(index: number): Promise\u003CT\u003E; }\nexport interface AspireDict\u003CTKey, TValue\u003E extends HandleReference { get(key: TKey): Promise\u003CTValue\u003E; }\nexport interface ResourceBuilderBase extends HandleReference {}\nexport interface InteractionInput { readonly name: string; }\nexport interface InteractionInputCollection extends HandleReference {}\nexport interface InteractionInputCollectionPromise extends PromiseLike\u003CInteractionInputCollection\u003E {}\nexport interface AspireClientRpc { readonly connected: boolean; invokeCapability\u003CTResult = unknown\u003E(capabilityId: string, args?: Record\u003Cstring, unknown\u003E): Promise\u003CTResult\u003E; }" - } - ] -} \ No newline at end of file diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.FocusedApiExport.verified.json b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.FocusedApiExport.verified.json new file mode 100644 index 00000000000..d4af4d0af50 --- /dev/null +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsTypeScriptCodeGeneratorTests.FocusedApiExport.verified.json @@ -0,0 +1,53 @@ +{ + "schemaVersion": 1, + "language": "typescript", + "generator": { + "name": "Aspire.Hosting.CodeGeneration.TypeScript", + "version": "13.5.0" + }, + "package": { + "name": "Aspire.Hosting.Contoso", + "version": "1.2.3" + }, + "modules": [ + { + "name": "index", + "items": [ + { + "id": "interface:ContosoResource", + "kind": "interface", + "name": "ContosoResource", + "typeId": "Aspire.Hosting.Contoso/ContosoResource", + "owningAssembly": "Aspire.Hosting.Contoso", + "declaration": "export interface ContosoResource", + "summary": "A Contoso resource.", + "members": [ + { + "id": "member:ContosoResource.configure", + "kind": "method", + "name": "configure", + "declaration": "configure(enabled?: boolean): Promise\u003Cvoid\u003E", + "capabilityId": "Aspire.Hosting.Contoso/configure", + "returnType": "Promise\u003Cvoid\u003E", + "parameters": [ + { + "name": "enabled", + "type": "boolean", + "optional": true, + "summary": "Whether configuration is enabled." + } + ] + } + ] + } + ] + } + ], + "declarations": [ + { + "id": "interface:ContosoResource", + "owningAssembly": "Aspire.Hosting.Contoso", + "content": "export interface ContosoResource {\n configure(enabled?: boolean): Promise\u003Cvoid\u003E;\n}" + } + ] +} \ No newline at end of file diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts index 15073dfea24..dd69cd4d341 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts @@ -1538,15 +1538,6 @@ export interface ArgOptions { defaultValue?: string; } -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { - name?: string; - isReadOnly?: boolean; -} - -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions { - mode?: TestPersistenceMode; -} - export interface BuildOptions { /** The logger used while resolving values. */ resourceLogger?: Awaitable; @@ -1731,6 +1722,11 @@ export interface WithContainerCertificatePathsOptions { defaultCertificateDirectoryPaths?: string[]; } +export interface WithDataVolumeOptions { + name?: string; + isReadOnly?: boolean; +} + export interface WithDescriptionOptions { /** A value indicating whether the description should be rendered as Markdown. `true` allows the description to contain Markdown elements such as links, text decoration and lists. */ enableMarkdown?: boolean; @@ -1890,6 +1886,10 @@ export interface WithOtlpExporterOptions { protocol?: OtlpProtocol; } +export interface WithPersistenceOptions { + mode?: TestPersistenceMode; +} + export interface WithPipelineStepFactoryOptions { /** Optional step names that this step depends on. */ dependsOn?: string[]; @@ -47378,7 +47378,7 @@ export interface TestRedisResource { * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -47445,7 +47445,7 @@ export interface TestRedisResource { * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -48251,7 +48251,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise; + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise; /** * Adds an optional string parameter * @param options Additional options. @@ -48318,7 +48318,7 @@ export interface TestRedisResourcePromise extends PromiseLike * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise; + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise; /** Adds a label to the resource */ withMergeLabel(label: string): TestRedisResourcePromise; /** Adds a categorized label to the resource */ @@ -50765,7 +50765,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Configures the Redis resource with persistence * @param options Additional options. */ - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { const mode = options?.mode; return new TestRedisResourcePromiseImpl(this._withPersistenceInternal(mode), this._client); } @@ -51182,7 +51182,7 @@ class TestRedisResourceImpl extends ResourceBuilderBase * Adds a data volume with persistence * @param options Additional options. */ - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { const name = options?.name; const isReadOnly = options?.isReadOnly; return new TestRedisResourcePromiseImpl(this._withDataVolumeInternal(name, isReadOnly), this._client); @@ -51721,7 +51721,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestDatabaseResourcePromiseImpl(this._promise.then(obj => obj.addTestChildDatabase(name, options)), this._client); } - withPersistence(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithPersistenceOptions): TestRedisResourcePromise { + withPersistence(options?: WithPersistenceOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withPersistence(options)), this._client); } @@ -51825,7 +51825,7 @@ class TestRedisResourcePromiseImpl implements TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withMultiParamHandleCallback(callback)), this._client); } - withDataVolume(options?: Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions): TestRedisResourcePromise { + withDataVolume(options?: WithDataVolumeOptions): TestRedisResourcePromise { return new TestRedisResourcePromiseImpl(this._promise.then(obj => obj.withDataVolume(options)), this._client); } diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts index 8bd1a447733..81e32543081 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/WithDataVolumeOptionsMerged.verified.ts @@ -1,4 +1,4 @@ -export interface Aspire_x002E_Hosting_x002E_CodeGeneration_x002E_TypeScript_x002E_Tests$WithDataVolumeOptions { +export interface WithDataVolumeOptions { name?: string; isReadOnly?: boolean; } \ No newline at end of file diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs index 1905fd7e3d4..ee341e8423c 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs @@ -116,51 +116,6 @@ public void GetAssemblyNamesToLoad_AddsAutoDiscoveredAssembliesFromPackageProbeM assemblyNames); } - [Fact] - public void GetAssemblyNamesToLoad_AddsAssembliesOwnedByConfiguredPackageFromProbeManifest() - { - using var manifestDirectory = new TemporaryDirectory(); - using var packageAssemblyDirectory = new TemporaryDirectory(); - - var primaryAssemblyPath = System.IO.Path.Combine(packageAssemblyDirectory.Path, "Contoso.Hosting.dll"); - var secondaryAssemblyPath = System.IO.Path.Combine(packageAssemblyDirectory.Path, "Contoso.Hosting.Extras.dll"); - var dependencyAssemblyPath = System.IO.Path.Combine(packageAssemblyDirectory.Path, "Dependency.Hosting.dll"); - File.WriteAllText(primaryAssemblyPath, string.Empty); - File.WriteAllText(secondaryAssemblyPath, string.Empty); - File.WriteAllText(dependencyAssemblyPath, string.Empty); - - var manifestPath = System.IO.Path.Combine(manifestDirectory.Path, "integration-package-probe-manifest.json"); - WriteProbeManifest( - manifestPath, - managedAssemblies: - [ - new { Name = "Contoso.Hosting", Path = primaryAssemblyPath, PackageId = "Contoso.Aspire.MetaPackage", PackageVersion = "1.2.3" }, - new { Name = "Contoso.Hosting.Extras", Path = secondaryAssemblyPath, PackageId = "Contoso.Aspire.MetaPackage", PackageVersion = "1.2.3" }, - new { Name = "Dependency.Hosting", Path = dependencyAssemblyPath, PackageId = "Dependency.Hosting", PackageVersion = "4.5.6" } - ]); - - var probeManifest = IntegrationPackageProbeManifest.Load(manifestPath); - var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - ["AtsAssemblies:0"] = "contoso.aspire.metapackage" - }) - .Build(); - - var assemblyNames = AssemblyLoader.GetAssemblyNamesToLoad( - configuration, - integrationLibsPath: null, - applicationBasePath: System.IO.Path.Combine(manifestDirectory.Path, "missing"), - packageProbeManifest: probeManifest); - - Assert.Equal( - [ - "Contoso.Hosting", - "Contoso.Hosting.Extras" - ], - assemblyNames); - } - [Fact] public void GetAssemblyNamesToLoad_CombinesPackageProbeManifestAndProjectLibs() { diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs index 98b1f2fabdc..916d1146eb6 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs @@ -563,68 +563,6 @@ public void ScanAssemblies_AssemblyLevelExportedTypes_AreResolvedAcrossScanOrder AtsCapabilityScanner.MapToAtsTypeId(typeof(AssemblyLevelExportedTestType))); } - /// - /// The ownership map is merged while assemblies are scanned, before the capability filters run. - /// An assembly whose every capability is filtered out must not stay in it: the map's values are - /// what AtsContextFilter.TryResolveCanonicalAssemblyName resolves a requested package - /// against, so a stale entry lets sdk export resolve the package, filter to nothing, and - /// report success while publishing an empty API document. - /// - /// - /// A method name collision is the reachable way to lose a capability after the map is built. - /// A capability whose parameter types do not map is skipped during discovery, so it never enters - /// the map in the first place; collisions are only detected once every assembly has been scanned. - /// Ordinal capability id order decides the loser, so the two assembly names are chosen to sort. - /// - [Fact] - public void ScanAssemblies_CapabilityLostToACollision_DropsItsAssemblyFromExportingAssemblyNames() - { - var hostingAssembly = typeof(IDistributedApplicationBuilder).Assembly; - var winningAssembly = CreateCollidingCapabilityAssembly("AaaCollisionWinner", "collidingExport"); - var losingAssembly = CreateCollidingCapabilityAssembly("ZzzCollisionLoser", "collidingExport"); - - var result = AtsCapabilityScanner.ScanAssemblies([hostingAssembly, winningAssembly, losingAssembly]); - - var losingAssemblyName = losingAssembly.GetName().Name!; - var winningAssemblyName = winningAssembly.GetName().Name!; - - Assert.Equal( - [winningAssemblyName], - result.Capabilities - .Where(c => c.CapabilityId.EndsWith("/collidingExport", StringComparison.Ordinal)) - .Select(c => c.CapabilityId.Split('/')[0]) - .Order(StringComparer.Ordinal)); - Assert.Equal( - new[] { hostingAssembly.GetName().Name!, winningAssemblyName }.Order(StringComparer.Ordinal), - result.CapabilityExportingAssemblyNames.Values.Distinct(StringComparer.Ordinal).Order(StringComparer.Ordinal)); - Assert.Equal( - result.Capabilities.Select(c => c.CapabilityId).Order(StringComparer.Ordinal), - result.CapabilityExportingAssemblyNames.Keys.Order(StringComparer.Ordinal)); - } - - /// - /// The single-assembly scan path builds the same registries ahead of the same filters and prunes - /// them for the same reason, so every registry must describe exactly the capabilities it kept. - /// - /// - /// This is an invariant guard rather than a reproduction. A capability id is - /// package/methodName, so two capabilities in one assembly cannot share a method name - /// without sharing an id, which makes an intra-assembly collision unremovable. The pruning this - /// asserts is reachable through FilterInvalidCapabilities, which both scan paths share. - /// - [Fact] - public void ScanAssembly_PerCapabilityRegistriesDescribeExactlyTheSurvivingCapabilities() - { - var result = AtsCapabilityScanner.ScanAssembly(typeof(IDistributedApplicationBuilder).Assembly); - - var survivingCapabilityIds = result.Capabilities.Select(c => c.CapabilityId).Distinct(StringComparer.Ordinal).Order(StringComparer.Ordinal).ToList(); - - Assert.NotEmpty(survivingCapabilityIds); - Assert.Equal(survivingCapabilityIds, result.CapabilityExportingAssemblyNames.Keys.Order(StringComparer.Ordinal)); - Assert.Empty(result.Methods.Keys.Except(survivingCapabilityIds, StringComparer.Ordinal)); - Assert.Empty(result.Properties.Keys.Except(survivingCapabilityIds, StringComparer.Ordinal)); - } - [Fact] public void ScanAssembly_YarpWithConfiguration_UsesBackgroundThreadOptIn() { @@ -1019,36 +957,6 @@ public static class Node } } - /// - /// Builds a dynamic assembly exporting a single capability under a caller-chosen method name, so - /// two of them can be made to collide on the same target. - /// - private static Assembly CreateCollidingCapabilityAssembly(string assemblyNamePrefix, string methodName) - { - var assemblyName = new AssemblyName($"{assemblyNamePrefix}_{Guid.NewGuid():N}"); - var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); - var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name!); - var exportsTypeBuilder = moduleBuilder.DefineType( - "Generated.CollidingExports", - TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed); - var methodBuilder = exportsTypeBuilder.DefineMethod( - "Collides", - MethodAttributes.Public | MethodAttributes.Static, - typeof(void), - [typeof(IDistributedApplicationBuilder), typeof(string)]); - methodBuilder.DefineParameter(1, ParameterAttributes.None, "builder"); - methodBuilder.DefineParameter(2, ParameterAttributes.None, "value"); - methodBuilder.SetCustomAttribute( - new CustomAttributeBuilder( - typeof(AspireExportAttribute).GetConstructor([typeof(string)])!, - [methodName])); - methodBuilder.GetILGenerator().Emit(OpCodes.Ret); - - _ = exportsTypeBuilder.CreateType(); - - return assemblyBuilder; - } - private static Assembly CreateAssemblyLevelExportCapabilityAssembly(Type parameterType) { var assemblyName = new AssemblyName($"AssemblyLevelExportCapability_{Guid.NewGuid():N}"); diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index 527ae9eca58..17502dbb402 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Reflection; -using System.Reflection.Emit; using System.Text.Json.Nodes; using Aspire.Hosting.ApplicationModel; using Aspire.TypeSystem; @@ -80,60 +79,6 @@ public enum NameCasing AsDeclared } - /// - /// An assembly whose capabilities were all removed by scan-time filtering exports nothing, so - /// canonicalization has to reject it. Resolving it instead is the silent failure: the export - /// filters to nothing and sdk export publishes an empty document under a successful exit - /// code rather than telling the caller the package contributed no API. - /// - [Fact] - public void TryResolveCanonicalAssemblyName_RejectsAnAssemblyWhoseCapabilitiesWereAllFiltered() - { - var losingAssembly = CreateCollidingCapabilityAssembly("ZzzFilterCollisionLoser"); - var context = AtsCapabilityScanner.ScanAssemblies( - [ - typeof(IDistributedApplicationBuilder).Assembly, - CreateCollidingCapabilityAssembly("AaaFilterCollisionWinner"), - losingAssembly - ]).ToAtsContext(); - var losingAssemblyName = losingAssembly.GetName().Name!; - - Assert.False(AtsContextFilter.TryResolveCanonicalAssemblyName(context, losingAssemblyName, out var resolvedName)); - Assert.Null(resolvedName); - Assert.Empty(AtsContextFilter.FilterByExportingAssemblies(context, [losingAssemblyName]).Capabilities); - } - - /// - /// A dynamic assembly whose single capability collides with an identically named export on the - /// same target, so the scan keeps only the ordinally first one and the other assembly is left - /// contributing nothing. - /// - private static Assembly CreateCollidingCapabilityAssembly(string assemblyNamePrefix) - { - var assemblyName = new AssemblyName($"{assemblyNamePrefix}_{Guid.NewGuid():N}"); - var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); - var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name!); - var exportsTypeBuilder = moduleBuilder.DefineType( - "Generated.CollidingExports", - TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed); - var methodBuilder = exportsTypeBuilder.DefineMethod( - "Collides", - MethodAttributes.Public | MethodAttributes.Static, - typeof(void), - [typeof(IDistributedApplicationBuilder), typeof(string)]); - methodBuilder.DefineParameter(1, ParameterAttributes.None, "builder"); - methodBuilder.DefineParameter(2, ParameterAttributes.None, "value"); - methodBuilder.SetCustomAttribute( - new CustomAttributeBuilder( - typeof(AspireExportAttribute).GetConstructor([typeof(string)])!, - ["collidingExport"])); - methodBuilder.GetILGenerator().Emit(OpCodes.Ret); - - _ = exportsTypeBuilder.CreateType(); - - return assemblyBuilder; - } - [Fact] public void FilterByExportingAssemblies_StrictFilterKeepsOnlySelectedAssemblyExports() { diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index 3bc44efda1e..ee46d4da0b9 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -8,6 +8,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; +using StreamJsonRpc; +using StreamJsonRpc.Protocol; using Xunit; namespace Aspire.Hosting.RemoteHost.Tests; @@ -25,8 +27,10 @@ public void ExportApi_TypeScript_ReturnsCanonicalSchemaForRequestedPackage() { var service = CreateCodeGenerationService(); - var export = service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0"); + var export = service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0", CancellationToken.None); + var repeatedExport = service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0", CancellationToken.None); + Assert.Equal(export.GetRawText(), repeatedExport.GetRawText()); Assert.Equal(1, export.GetProperty("schemaVersion").GetInt32()); Assert.Equal("typescript", export.GetProperty("language").GetString()); Assert.Equal("Aspire.Hosting", export.GetProperty("package").GetProperty("name").GetString()); @@ -53,7 +57,7 @@ public void ExportApi_ScopesDocumentedItemsToRequestedPackage() { var service = CreateCodeGenerationService(); - var export = service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0"); + var export = service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0", CancellationToken.None); // Referenced types reach the export through the closure so the declarations type-check, but // they must not be documented here: the package that owns them publishes them. @@ -87,10 +91,27 @@ public void ExportApi_ScopesDocumentedItemsToRequestedPackage() } [Fact] - public void ExportApi_UsesPackageProbeManifestAssembliesForRequestedPackage() + public void ExportApi_UsesGlobalPackagesPathsForRequestedPackage() { using var manifestDirectory = new TemporaryDirectory(); var manifestPath = Path.Combine(manifestDirectory.Path, "integration-package-probe-manifest.json"); + var packageAssetsPath = Path.Combine( + manifestDirectory.Path, + "packages", + "contoso.aspire.metapackage", + "1.2.3"); + + var hostingAssemblyPath = CopyPackageAssembly( + typeof(IDistributedApplicationBuilder).Assembly.Location, + packageAssetsPath, + "lib", + "net8.0"); + var yarpAssemblyPath = CopyPackageAssembly( + typeof(Yarp.YarpResource).Assembly.Location, + packageAssetsPath, + "REF", + "NET8.0"); + WriteProbeManifest( manifestPath, managedAssemblies: @@ -98,25 +119,24 @@ public void ExportApi_UsesPackageProbeManifestAssembliesForRequestedPackage() new { Name = "Aspire.Hosting", - Path = typeof(IDistributedApplicationBuilder).Assembly.Location, - PackageId = "Contoso.Aspire.MetaPackage", - PackageVersion = "1.2.3" + Path = hostingAssemblyPath }, new { Name = "Aspire.Hosting.Yarp", - Path = typeof(Yarp.YarpResource).Assembly.Location, - PackageId = "Contoso.Aspire.MetaPackage", - PackageVersion = "1.2.3" + Path = yarpAssemblyPath } ]); var service = CreateCodeGenerationService(new Dictionary { - ["AtsAssemblies:0"] = "Contoso.Aspire.MetaPackage", ["ASPIRE_INTEGRATION_PROBE_MANIFEST_PATH"] = manifestPath }); - var export = service.ExportApi("TypeScript", "contoso.aspire.metapackage", "1.2.3"); + var versionMismatch = Assert.Throws( + () => service.ExportApi("TypeScript", "Contoso.Aspire.MetaPackage", "9.9.9", CancellationToken.None)); + Assert.Contains("9.9.9", versionMismatch.Message, StringComparison.Ordinal); + + var export = service.ExportApi("TypeScript", "Contoso.Aspire.MetaPackage", "1.2.3", CancellationToken.None); Assert.Equal("Contoso.Aspire.MetaPackage", export.GetProperty("package").GetProperty("name").GetString()); @@ -135,8 +155,9 @@ public void ExportApi_UnknownLanguage_ListsAvailableLanguages() { var service = CreateCodeGenerationService(); - var ex = Assert.Throws(() => service.ExportApi("klingon", "Aspire.Hosting", "13.5.0")); + var ex = Assert.Throws(() => service.ExportApi("klingon", "Aspire.Hosting", "13.5.0", CancellationToken.None)); + Assert.Equal((int)JsonRpcErrorCode.InvalidParams, ex.ErrorCode); Assert.Contains("No code generator found for language: klingon", ex.Message); Assert.Contains("Available languages:", ex.Message); } @@ -149,8 +170,9 @@ public void ExportApi_GeneratorWithoutExporter_ReportsUnsupportedLanguage() // Go generates runtime source but ships no IApiReferenceExporter, so asking it for // an API export has to fail with a message that names the gap rather than returning an empty // document that a documentation site would silently publish. - var ex = Assert.Throws(() => service.ExportApi("Go", "Aspire.Hosting", "13.5.0")); + var ex = Assert.Throws(() => service.ExportApi("Go", "Aspire.Hosting", "13.5.0", CancellationToken.None)); + Assert.Equal((int)JsonRpcErrorCode.InvalidParams, ex.ErrorCode); Assert.Contains("Go", ex.Message, StringComparison.Ordinal); Assert.Contains(nameof(IApiReferenceExporter), ex.Message, StringComparison.Ordinal); } @@ -163,7 +185,8 @@ public void ExportApi_MissingPackageName_Throws(string? packageName) { var service = CreateCodeGenerationService(); - Assert.ThrowsAny(() => service.ExportApi("TypeScript", packageName!, "13.5.0")); + var ex = Assert.Throws(() => service.ExportApi("TypeScript", packageName!, "13.5.0", CancellationToken.None)); + Assert.Equal((int)JsonRpcErrorCode.InvalidParams, ex.ErrorCode); } [Theory] @@ -174,7 +197,8 @@ public void ExportApi_MissingPackageVersion_Throws(string? packageVersion) { var service = CreateCodeGenerationService(); - Assert.ThrowsAny(() => service.ExportApi("TypeScript", "Aspire.Hosting", packageVersion!)); + var ex = Assert.Throws(() => service.ExportApi("TypeScript", "Aspire.Hosting", packageVersion!, CancellationToken.None)); + Assert.Equal((int)JsonRpcErrorCode.InvalidParams, ex.ErrorCode); } [Fact] @@ -182,7 +206,7 @@ public void ExportApi_RequiresAuthentication() { var service = CreateCodeGenerationService(authenticated: false); - Assert.ThrowsAny(() => service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0")); + Assert.ThrowsAny(() => service.ExportApi("TypeScript", "Aspire.Hosting", "13.5.0", CancellationToken.None)); } private static CodeGenerationService CreateCodeGenerationService( @@ -250,6 +274,19 @@ private static void WriteProbeManifest(string manifestPath, IEnumerable? })); } + private static string CopyPackageAssembly( + string assemblyPath, + string packageAssetsPath, + string assetKind, + string targetFramework) + { + var destinationDirectory = Path.Combine(packageAssetsPath, assetKind, targetFramework); + Directory.CreateDirectory(destinationDirectory); + var destinationPath = Path.Combine(destinationDirectory, Path.GetFileName(assemblyPath)); + File.Copy(assemblyPath, destinationPath); + return destinationPath; + } + private sealed class TemporaryDirectory : IDisposable { private readonly DirectoryInfo _directory; diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs index 96fcdc457b3..4fbef60dd61 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs @@ -188,15 +188,11 @@ public async Task ManifestCommand_WritesPackageProbeManifestWithoutCreatingLibsL Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Test.Package" && - assembly.GetProperty("packageId").GetString() == "Test.Package" && - assembly.GetProperty("packageVersion").GetString() == "1.0.0" && assembly.GetProperty("path").GetString() == Path.Combine(packageRoot, GetExpectedRuntimeAssemblyPath().Replace('/', Path.DirectorySeparatorChar))); Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Test.Package.resources" && assembly.GetProperty("culture").GetString() == "fr" && - assembly.GetProperty("packageId").GetString() == "Test.Package" && - assembly.GetProperty("packageVersion").GetString() == "1.0.0" && assembly.GetProperty("path").GetString() == Path.Combine(packageRoot, "lib", "net10.0", "fr", "Test.Package.resources.dll")); var nativeLibraries = manifest.RootElement.GetProperty("nativeLibraries").EnumerateArray().ToList(); @@ -265,8 +261,6 @@ public async Task RestoreAndManifestCommands_WritePackageCacheManifestWithoutCre Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Test.Package" && - assembly.GetProperty("packageId").GetString() == "Test.Package" && - assembly.GetProperty("packageVersion").GetString() == "1.0.0" && assembly.GetProperty("path").GetString() == expectedAssemblyPath); Assert.DoesNotContain( managedAssemblies, diff --git a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs index 6f38b509abb..623851d5c2e 100644 --- a/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs +++ b/tests/Infrastructure.Tests/TypeScriptApiCompat/TypeScriptApiCompatTests.cs @@ -30,7 +30,7 @@ public void ParserReadsAtsCiSurface() Configs.Default: string = "dev" # copied value # Capabilities - Pkg/addThing(name: string, port?: number, endpoint: string?) -> Pkg/Thing + Pkg/addThing(name: string, port?: number) -> Pkg/Thing """); var handle = Assert.Single(surface.HandleTypes.Values); @@ -55,11 +55,6 @@ public void ParserReadsAtsCiSurface() Assert.Equal("Pkg/Thing", capability.ReturnTypeId); Assert.Equal("port", capability.Parameters[1].Name); Assert.True(capability.Parameters[1].IsOptional); - Assert.False(capability.Parameters[1].IsNullable); - Assert.Equal("endpoint", capability.Parameters[2].Name); - Assert.False(capability.Parameters[2].IsOptional); - Assert.True(capability.Parameters[2].IsNullable); - Assert.Equal("string", capability.Parameters[2].TypeId); } [Fact] @@ -195,31 +190,6 @@ public void ComparerClassifiesBreakingAndAdditiveChanges() Assert.DoesNotContain(diagnostics, d => d.Symbol is "Pkg/NewThing" or "Pkg/newCapability" or "Pkg/addThing(optionalName)" or "Pkg/Options.newOptional" or "Pkg/addInputType(name)"); } - [Fact] - public void NullableCapabilityParametersUseTheSameEffectiveOptionalRuleAsTheProjector() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - WriteSurface(baselineRoot, "Pkg", """ - # Capabilities - Pkg/addThing(name: string, wasNullable: string?) -> void - """); - WriteSurface(currentRoot, "Pkg", """ - # Capabilities - Pkg/addThing(name: string, wasNullable: string, addedNullable: number?) -> void - """); - - var diagnostics = AtsCompatibilityComparer.Compare(AtsSurfaceSet.Load(baselineRoot), AtsSurfaceSet.Load(currentRoot)); - - // The projector emits a nullable parameter as `name?: type`, so dropping the nullability makes - // a parameter TypeScript callers could omit into one they cannot, and adding a nullable one - // breaks nobody. - Assert.Contains(diagnostics, d => d.Kind == "capability-parameter-required" && d.Symbol == "Pkg/addThing(wasNullable)"); - Assert.DoesNotContain(diagnostics, d => d.Kind == "capability-parameter-added-required"); - } - [Fact] public void SuppressionsUseExactMatchesAndFailWhenUnused() { @@ -353,316 +323,6 @@ public void RunnerIgnoresExcludedPackagesAndSuppressions() Assert.DoesNotContain("Unused suppressions", report, StringComparison.Ordinal); } - [Fact] - public void RunnerFailsWhenUnqualifiedOptionsInterfaceNamesCollide() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - WriteSurface(baselineRoot, "Pkg.One", """ - # Capabilities - Pkg.One/withShared(port?: number) -> void - """); - WriteSurface(baselineRoot, "Pkg.Two", """ - # Capabilities - Pkg.Two/withShared(host?: string) -> void - """); - WriteSurface(currentRoot, "Pkg.One", """ - # Capabilities - Pkg.One/withShared(port?: number) -> void - """); - WriteSurface(currentRoot, "Pkg.Two", """ - # Capabilities - Pkg.Two/withShared(host?: string) -> void - """); - - // The writer is injected rather than swapped in through Console.SetError: xUnit runs test - // classes in parallel, so replacing the process-wide console lets one test capture another - // test's output and lets another test restore the writer mid-assertion. - using var error = new StringWriter(); - - var exitCode = TypeScriptApiCompatRunner.Run( - new CommandLineOptions( - baselineRoot, - currentRoot, - workspace.Path, - BaselineSuppressionsRoot: null, - ExcludedPackagesFile: null, - ReportPath: null, - GitHubAnnotations: false), - error); - - Assert.Equal(2, exitCode); - - var message = error.ToString(); - Assert.Contains("Unqualified TypeScript options interface collision", message, StringComparison.Ordinal); - Assert.Contains("WithSharedOptions", message, StringComparison.Ordinal); - Assert.Contains("'Pkg.One'", message, StringComparison.Ordinal); - Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); - Assert.Contains("Remedy:", message, StringComparison.Ordinal); - } - - [Fact] - public void RunnerFailsWhenNullableParametersProduceUnqualifiedOptionsInterfaceCollision() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - WriteSurface(baselineRoot, "Pkg.One", """ - # Capabilities - Pkg.One/withShared(port: number?) -> void - """); - WriteSurface(baselineRoot, "Pkg.Two", """ - # Capabilities - Pkg.Two/withShared(host: string?) -> void - """); - WriteSurface(currentRoot, "Pkg.One", """ - # Capabilities - Pkg.One/withShared(port: number?) -> void - """); - WriteSurface(currentRoot, "Pkg.Two", """ - # Capabilities - Pkg.Two/withShared(host: string?) -> void - """); - - // The writer is injected rather than swapped in through Console.SetError: xUnit runs test - // classes in parallel, so replacing the process-wide console lets one test capture another - // test's output and lets another test restore the writer mid-assertion. - using var error = new StringWriter(); - - var exitCode = TypeScriptApiCompatRunner.Run( - new CommandLineOptions( - baselineRoot, - currentRoot, - workspace.Path, - BaselineSuppressionsRoot: null, - ExcludedPackagesFile: null, - ReportPath: null, - GitHubAnnotations: false), - error); - - Assert.Equal(2, exitCode); - - var message = error.ToString(); - Assert.Contains("WithSharedOptions", message, StringComparison.Ordinal); - Assert.Contains("'Pkg.One'", message, StringComparison.Ordinal); - Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); - } - - [Fact] - public void RunnerFailsWhenAliasedCapabilitiesProjectToTheSameOptionsInterface() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - // Both packages alias distinct capability ids onto the same projected method, which is what - // [AspireExport("withRedisCommanderHostPort", MethodName = "withHostPort")] does. The ids do - // not collide; the generated WithProbePortOptions interfaces do. The projected name is - // deliberately absent from PackageQualifiedOptionsInterfaceNames, because a name on that - // list is qualified and so cannot collide. - foreach (var root in new[] { baselineRoot, currentRoot }) - { - WriteSurface(root, "Pkg.One", """ - # Capabilities - Pkg.One/withCommanderProbePort(port?: number) -> void [method=withProbePort] - """); - WriteSurface(root, "Pkg.Two", """ - # Capabilities - Pkg.Two/withInsightProbePort(port?: number) -> void [method=withProbePort] - """); - } - - using var error = new StringWriter(); - - var exitCode = TypeScriptApiCompatRunner.Run( - new CommandLineOptions( - baselineRoot, - currentRoot, - workspace.Path, - BaselineSuppressionsRoot: null, - ExcludedPackagesFile: null, - ReportPath: null, - GitHubAnnotations: false), - error); - - Assert.Equal(2, exitCode); - - var message = error.ToString(); - Assert.Contains("WithProbePortOptions", message, StringComparison.Ordinal); - Assert.Contains("'Pkg.One'", message, StringComparison.Ordinal); - Assert.Contains("'Pkg.Two'", message, StringComparison.Ordinal); - } - - /// - /// The shipped surface really does produce the two collisions that only became visible once the - /// guard started naming the interface after the projected method: Docker's - /// addComposeFileSecret projects as addSecret next to Key Vault's addSecret, - /// and eleven packages project withHostPort. Both unqualified names are in - /// PackageQualifiedOptionsInterfaceNames, so those packages emit package-qualified - /// interfaces and the guard has to stay quiet. Dropping either entry puts a conflicting - /// unqualified declaration back into the concatenated package exports, which is the exact - /// failure this repository shipped to CI before those entries were added. - /// - [Fact] - public void RunnerAllowsShippedAliasCollisionsThatPackageQualifiedNamesAlreadyResolve() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - // Trimmed from the surfaces `aspire sdk dump --format ci` actually emits for these packages. - foreach (var root in new[] { baselineRoot, currentRoot }) - { - WriteSurface(root, "Aspire.Hosting.Azure.KeyVault", """ - # Capabilities - Aspire.Hosting.Azure.KeyVault/addSecret(name: string, value?: string) -> void - """); - WriteSurface(root, "Aspire.Hosting.Docker", """ - # Capabilities - Aspire.Hosting.Docker/addComposeFileSecret(name: string, value?: string) -> void [method=addSecret] - Aspire.Hosting.Docker/withHostPort(port?: number) -> void - """); - WriteSurface(root, "Aspire.Hosting.Redis", """ - # Capabilities - Aspire.Hosting.Redis/withHostPort(port?: number) -> void - Aspire.Hosting.Redis/withRedisCommanderHostPort(port?: number) -> void [method=withHostPort] - """); - WriteSurface(root, "Aspire.Hosting.PostgreSQL", """ - # Capabilities - Aspire.Hosting.PostgreSQL/withPgAdminHostPort(port?: number) -> void [method=withHostPort] - """); - } - - using var error = new StringWriter(); - - var exitCode = TypeScriptApiCompatRunner.Run( - new CommandLineOptions( - baselineRoot, - currentRoot, - workspace.Path, - BaselineSuppressionsRoot: null, - ExcludedPackagesFile: null, - ReportPath: null, - GitHubAnnotations: false), - error); - - // Assert the guard output before the exit code so a regression reports the collision text - // instead of just "expected 0, actual 2". - Assert.Equal(string.Empty, error.ToString()); - Assert.Equal(0, exitCode); - } - - [Fact] - public void RunnerAllowsSharedCapabilityIdsThatProjectToDifferentMethodNames() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - foreach (var root in new[] { baselineRoot, currentRoot }) - { - WriteSurface(root, "Pkg.One", """ - # Capabilities - Pkg.One/withShared(port?: number) -> void [method=withOnePort] - """); - WriteSurface(root, "Pkg.Two", """ - # Capabilities - Pkg.Two/withShared(host?: string) -> void [method=withTwoHost] - """); - } - - using var error = new StringWriter(); - - var exitCode = TypeScriptApiCompatRunner.Run( - new CommandLineOptions( - baselineRoot, - currentRoot, - workspace.Path, - BaselineSuppressionsRoot: null, - ExcludedPackagesFile: null, - ReportPath: null, - GitHubAnnotations: false), - error); - - Assert.Equal(0, exitCode); - Assert.DoesNotContain("collision", error.ToString(), StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void ComparerTreatsTheProjectedMethodAnnotationAsSurfaceMetadataRatherThanTheReturnType() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - // Baselines written before the annotation existed carry no [method=...] suffix, so the - // annotation has to be split off the return type or every aliased capability would look - // like its return type changed the first time a surface is regenerated. - WriteSurface(baselineRoot, "Pkg", """ - # Capabilities - Pkg/withCommanderHostPort(port?: number) -> void - """); - WriteSurface(currentRoot, "Pkg", """ - # Capabilities - Pkg/withCommanderHostPort(port?: number) -> void [method=withHostPort] - """); - - using var error = new StringWriter(); - - var exitCode = TypeScriptApiCompatRunner.Run( - new CommandLineOptions( - baselineRoot, - currentRoot, - workspace.Path, - BaselineSuppressionsRoot: null, - ExcludedPackagesFile: null, - ReportPath: null, - GitHubAnnotations: false), - error); - - Assert.Equal(0, exitCode); - } - - [Fact] - public void ComparerReportsARenamedProjectedMethodOnceTheBaselineRecordsIt() - { - using var workspace = TemporaryWorkspace.Create(outputHelper); - var baselineRoot = Path.Combine(workspace.Path, "baseline"); - var currentRoot = Path.Combine(workspace.Path, "current"); - - // The capability id is unchanged, so nothing else in the comparison notices -- but the - // generated TypeScript method is renamed, which breaks callers exactly like a removal. - WriteSurface(baselineRoot, "Pkg", """ - # Capabilities - Pkg/withCommanderHostPort(port?: number) -> void [method=withHostPort] - """); - WriteSurface(currentRoot, "Pkg", """ - # Capabilities - Pkg/withCommanderHostPort(port?: number) -> void [method=withOtherPort] - """); - - var reportPath = Path.Combine(workspace.Path, "report.md"); - - var exitCode = TypeScriptApiCompatRunner.Run(new CommandLineOptions( - baselineRoot, - currentRoot, - workspace.Path, - BaselineSuppressionsRoot: null, - ExcludedPackagesFile: null, - ReportPath: reportPath, - GitHubAnnotations: false)); - - Assert.Equal(1, exitCode); - - var report = File.ReadAllText(reportPath); - Assert.Contains("capability-method-renamed", report, StringComparison.Ordinal); - Assert.Contains("withHostPort", report, StringComparison.Ordinal); - Assert.Contains("withOtherPort", report, StringComparison.Ordinal); - } - private static void WriteSurface(string rootPath, string packageName, string content) { var apiDirectory = Path.Combine(rootPath, "src", packageName, "api"); diff --git a/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs b/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs index 7932ec3ff33..a343b775891 100644 --- a/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs +++ b/tools/TypeScriptApiCompat/AtsCompatibilityComparer.cs @@ -230,32 +230,10 @@ private static void CompareCapabilities(AtsSurface baseline, AtsSurface current, $"Capability '{capabilityId}' return type changed from '{baselineCapability.ReturnTypeId}' to '{currentCapability.ReturnTypeId}'.")); } - // Renaming the projected method renames the generated TypeScript method even though the - // capability id is unchanged, so it breaks callers exactly like a removal would. Only an - // annotated baseline can be compared: an unannotated one has the name inferred from the - // id, so comparing it would report every aliased export as renamed on the single - // regeneration that first writes the annotations. - if (baselineCapability.ProjectedMethodNameWasRecorded && - !string.Equals(baselineCapability.ProjectedMethodName, currentCapability.ProjectedMethodName, StringComparison.Ordinal)) - { - diagnostics.Add(new ApiCompatDiagnostic( - "capability-method-renamed", - baseline.PackageName, - capabilityId, - $"Capability '{capabilityId}' projected method name changed from '{baselineCapability.ProjectedMethodName}' to '{currentCapability.ProjectedMethodName}'.")); - } - CompareCapabilityParameters(baseline.PackageName, baselineCapability, currentCapability, diagnostics); } } - // A nullable parameter projects to an optional TypeScript parameter (`name?: type`), so the - // TypeScript projector treats IsOptional || IsNullable as optional. Comparing on IsOptional alone - // would call a newly added nullable parameter a breaking addition and would miss a nullable - // parameter becoming non-nullable, which really does break existing callers. - private static bool IsEffectivelyOptional(AtsParameter parameter) - => parameter.IsOptional || parameter.IsNullable; - private static void CompareCapabilityParameters( string packageName, AtsCapability baselineCapability, @@ -287,7 +265,7 @@ private static void CompareCapabilityParameters( $"Capability parameter '{symbol}' type changed from '{baselineParameter.TypeId}' to '{currentParameter.TypeId}'.")); } - if (IsEffectivelyOptional(baselineParameter) && !IsEffectivelyOptional(currentParameter)) + if (baselineParameter.IsOptional && !currentParameter.IsOptional) { diagnostics.Add(new ApiCompatDiagnostic( "capability-parameter-required", @@ -299,7 +277,7 @@ private static void CompareCapabilityParameters( foreach (var currentParameter in currentCapability.Parameters) { - if (!IsEffectivelyOptional(currentParameter) && !baselineByName.ContainsKey(currentParameter.Name)) + if (!currentParameter.IsOptional && !baselineByName.ContainsKey(currentParameter.Name)) { var symbol = $"{baselineCapability.CapabilityId}({currentParameter.Name})"; diagnostics.Add(new ApiCompatDiagnostic( diff --git a/tools/TypeScriptApiCompat/AtsSurface.cs b/tools/TypeScriptApiCompat/AtsSurface.cs index 7cfd2e1a6fa..632b20dce13 100644 --- a/tools/TypeScriptApiCompat/AtsSurface.cs +++ b/tools/TypeScriptApiCompat/AtsSurface.cs @@ -21,28 +21,9 @@ internal sealed record AtsEnumType(string TypeId, IReadOnlyList Values); internal sealed record AtsExportedValue(string Path, string TypeId, string Value); -/// The exported capability id, for example Pkg/withRedisCommanderHostPort. -/// The exported parameters, in declaration order. -/// The exported return type id. -/// -/// The TypeScript method name the projector emits, which [AspireExport(..., MethodName = "...")] -/// can make differ from the capability id. This is what the options interface is named after, so the -/// collision guard has to use it rather than the id. -/// -/// -/// Whether the surface actually carried the projected name rather than having it inferred from the -/// capability id. Surfaces written before the annotation existed carry nothing, and comparing an -/// inferred name against a recorded one would report every aliased export as renamed the first time -/// a baseline is regenerated. -/// -internal sealed record AtsCapability( - string CapabilityId, - IReadOnlyList Parameters, - string ReturnTypeId, - string ProjectedMethodName, - bool ProjectedMethodNameWasRecorded); - -internal sealed record AtsParameter(string Name, string TypeId, bool IsOptional, bool IsNullable); +internal sealed record AtsCapability(string CapabilityId, IReadOnlyList Parameters, string ReturnTypeId); + +internal sealed record AtsParameter(string Name, string TypeId, bool IsOptional); internal sealed class AtsSurfaceSet { diff --git a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs index 600fec0fde2..9f04fbfb0bf 100644 --- a/tools/TypeScriptApiCompat/AtsSurfaceParser.cs +++ b/tools/TypeScriptApiCompat/AtsSurfaceParser.cs @@ -207,31 +207,7 @@ private static AtsCapability ParseCapability(string line) .Select(ParseParameter) .ToArray(); - // A capability whose projected TypeScript method name differs from its id carries that name - // as a trailing annotation: - // Pkg/withRedisCommanderHostPort(port?: number) -> Pkg/Handle [method=withHostPort] - // The annotation is emitted only for the aliased minority, so an unannotated line -- every - // line in a surface written before this existed -- projects under its own id. - var projectedMethodName = GetMethodNameSegment(capabilityId); - var projectedMethodNameWasRecorded = false; - var annotationIndex = returnTypeId.IndexOf(MethodAnnotationPrefix, StringComparison.Ordinal); - if (annotationIndex >= 0 && returnTypeId.EndsWith(']')) - { - var start = annotationIndex + MethodAnnotationPrefix.Length; - projectedMethodName = returnTypeId[start..^1]; - returnTypeId = returnTypeId[..annotationIndex]; - projectedMethodNameWasRecorded = true; - } - - return new AtsCapability(capabilityId, parameters, returnTypeId, projectedMethodName, projectedMethodNameWasRecorded); - } - - private const string MethodAnnotationPrefix = " [method="; - - private static string GetMethodNameSegment(string capabilityId) - { - var slashIndex = capabilityId.IndexOf('/'); - return slashIndex < 0 ? capabilityId : capabilityId[(slashIndex + 1)..]; + return new AtsCapability(capabilityId, parameters, returnTypeId); } private static AtsParameter ParseParameter(string parameterText) @@ -242,19 +218,12 @@ private static AtsParameter ParseParameter(string parameterText) throw new InvalidDataException($"Invalid parameter '{parameterText}'."); } - // Capability parameters are emitted as: - // name?: type? // optional nullable parameter - // options: Pkg/Options? // required parameter whose nullability still generates an options bag - // Optionality lives on the parameter name, and nullability lives on the type token so the - // compat guard can mirror the TypeScript projector's `IsOptional || IsNullable` rule. var nameText = parameterText[..separatorIndex]; var isOptional = nameText.EndsWith('?'); var name = isOptional ? nameText[..^1] : nameText; - var typeText = parameterText[(separatorIndex + 2)..]; - var isNullable = typeText.EndsWith('?'); - var typeId = isNullable ? typeText[..^1] : typeText; + var typeId = parameterText[(separatorIndex + 2)..]; - return new AtsParameter(name, typeId, isOptional, isNullable); + return new AtsParameter(name, typeId, isOptional); } private static string StripDescription(string value) diff --git a/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj b/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj index 2c3529be2c3..2bb117d795c 100644 --- a/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj +++ b/tools/TypeScriptApiCompat/TypeScriptApiCompat.csproj @@ -15,8 +15,4 @@ - - - - diff --git a/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs b/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs index d467fc1efca..6d9216234c4 100644 --- a/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs +++ b/tools/TypeScriptApiCompat/TypeScriptApiCompatRunner.cs @@ -5,23 +5,13 @@ namespace TypeScriptApiCompat; internal static class TypeScriptApiCompatRunner { - /// - /// Runs the TypeScript API compatibility comparison and writes its report. - /// - /// The parsed command line options. - /// - /// Where failure messages go. Defaults to for the command line, and is - /// injected by tests so they can read the message without replacing the process-wide console, - /// which xUnit's parallel classes would otherwise race on. - /// - public static int Run(CommandLineOptions options, TextWriter? errorWriter = null) + public static int Run(CommandLineOptions options) { try { var excludedPackages = ExcludedPackageLoader.Load(options.ExcludedPackagesFile); var baseline = AtsSurfaceSet.Load(options.BaselinePath); var current = AtsSurfaceSet.Load(options.CurrentPath); - TypeScriptOptionsCollisionGuard.Validate(current); var diagnostics = AtsCompatibilityComparer.Compare(baseline, current, excludedPackages); var suppressionLoadResult = ApiCompatSuppressionLoader.Load(options.SuppressionsRoot); var baselineSuppressionLoadResult = options.BaselineSuppressionsRoot is null @@ -52,7 +42,7 @@ public static int Run(CommandLineOptions options, TextWriter? errorWriter = null } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or InvalidDataException or InvalidOperationException) { - (errorWriter ?? Console.Error).WriteLine(ex.Message); + Console.Error.WriteLine(ex.Message); return 2; } } diff --git a/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs b/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs deleted file mode 100644 index e46a61f7b04..00000000000 --- a/tools/TypeScriptApiCompat/TypeScriptOptionsCollisionGuard.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text; -using Aspire.Shared.CodeGeneration; - -namespace TypeScriptApiCompat; - -internal static class TypeScriptOptionsCollisionGuard -{ - public static void Validate(AtsSurfaceSet surfaceSet) - { - var dtoTypeIds = surfaceSet.Surfaces.Values - .SelectMany(static surface => surface.DtoTypes.Keys) - .ToHashSet(StringComparer.Ordinal); - var candidates = new List(); - - foreach (var surface in surfaceSet.Surfaces.Values.OrderBy(static surface => surface.PackageName, StringComparer.Ordinal)) - { - foreach (var capability in surface.Capabilities.Values.OrderBy(static capability => capability.CapabilityId, StringComparer.Ordinal)) - { - var optionsParameters = capability.Parameters - .Where(static parameter => parameter.IsOptional || parameter.IsNullable) - .ToArray(); - - if (optionsParameters.Length == 0 || IsDirectOptionsParameter(optionsParameters, dtoTypeIds)) - { - continue; - } - - // The options interface is named after the projected method name, which - // [AspireExport(..., MethodName = "...")] can make differ from the capability id: - // Redis Commander exports withRedisCommanderHostPort but projects as withHostPort, - // so naming from the id would check WithRedisCommanderHostPortOptions while the - // generator emits WithHostPortOptions and the real collision goes unseen. - var interfaceName = GetUnqualifiedOptionsInterfaceName(capability.ProjectedMethodName); - if (!TypeScriptOptionsInterfaceNaming.RequiresPackageQualifier(interfaceName)) - { - candidates.Add(new OptionsInterfaceCandidate(interfaceName, surface.PackageName, capability.CapabilityId)); - } - } - } - - var collisions = candidates - .GroupBy(static candidate => candidate.InterfaceName, StringComparer.Ordinal) - .Select(static group => new OptionsInterfaceCollision( - group.Key, - group.ToArray(), - group.Select(static candidate => candidate.PackageName).Distinct(StringComparer.Ordinal).ToArray())) - .Where(static collision => collision.PackageNames.Count > 1) - .OrderBy(static collision => collision.InterfaceName, StringComparer.Ordinal) - .ToArray(); - - if (collisions.Length > 0) - { - throw new InvalidOperationException(CreateCollisionMessage(collisions)); - } - } - - private static bool IsDirectOptionsParameter(IReadOnlyList optionsParameters, IReadOnlySet dtoTypeIds) - { - var candidates = optionsParameters - .Where(static parameter => !IsCancellationToken(parameter)) - .ToArray(); - - return candidates.Length == 1 && - string.Equals(candidates[0].Name, "options", StringComparison.Ordinal) && - !string.Equals(candidates[0].TypeId, "callback", StringComparison.Ordinal) && - dtoTypeIds.Contains(candidates[0].TypeId); - } - - private static string GetUnqualifiedOptionsInterfaceName(string projectedMethodName) - => TypeScriptOptionsInterfaceNaming.GetUnqualifiedOptionsInterfaceName(projectedMethodName); - - private static string CreateCollisionMessage(IReadOnlyList collisions) - { - var builder = new StringBuilder(); - builder.AppendLine("Unqualified TypeScript options interface collision detected."); - - foreach (var collision in collisions) - { - builder.Append("- "); - builder.Append(collision.InterfaceName); - builder.Append(": "); - - var packageSummaries = collision.Candidates - .GroupBy(static candidate => candidate.PackageName, StringComparer.Ordinal) - .OrderBy(static group => group.Key, StringComparer.Ordinal) - .Select(static group => $"'{group.Key}' ({string.Join(", ", group.Select(candidate => candidate.CapabilityId).Order(StringComparer.Ordinal))})") - .ToArray(); - - if (packageSummaries.Length == 2) - { - builder.Append(packageSummaries[0]); - builder.Append(" and "); - builder.Append(packageSummaries[1]); - builder.Append(" both produce this unqualified options interface."); - } - else - { - builder.Append("these packages produce this unqualified options interface: "); - builder.Append(string.Join("; ", packageSummaries)); - builder.Append('.'); - } - - builder.AppendLine(); - } - - builder.Append("Remedy: add the unqualified interface name to "); - builder.Append(nameof(TypeScriptOptionsInterfaceNaming)); - builder.Append('.'); - builder.Append(nameof(TypeScriptOptionsInterfaceNaming.PackageQualifiedOptionsInterfaceNames)); - builder.Append(" so non-core packages use package-qualified options names, then update the TypeScript API compatibility baselines."); - - return builder.ToString(); - } - - private static bool IsCancellationToken(AtsParameter parameter) - => string.Equals(parameter.TypeId, "cancellationToken", StringComparison.Ordinal); - - private sealed record OptionsInterfaceCandidate(string InterfaceName, string PackageName, string CapabilityId); - - private sealed record OptionsInterfaceCollision( - string InterfaceName, - IReadOnlyList Candidates, - IReadOnlyList PackageNames); -} From 024178aed62da081cd3d25c7f6151ecfcb55b253 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 17:06:49 -0400 Subject: [PATCH 56/73] Address focused API export review findings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c235246b-d021-4d8e-b041-cc4984674ebe --- .../Commands/Sdk/SdkExportCommand.cs | 4 ++- .../TypeScriptApiProjector.cs | 16 ++++++--- .../AssemblyLoader.cs | 15 +++++++-- .../ApiReferenceExportOptions.cs | 15 +++++++-- .../IApiReferenceExporter.cs | 15 ++++++++- .../Commands/Sdk/SdkExportCommandTests.cs | 22 +++++++++++++ .../AtsTypeScriptCodeGeneratorTests.cs | 33 +++++++++++++++++-- .../CodeGeneration/ApiReferenceExportTests.cs | 9 ++--- 8 files changed, 112 insertions(+), 17 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 9a898c29e32..421b1d01670 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -102,7 +102,9 @@ protected override async Task ExecuteAsync(ParseResult parseResul languageInfo.LanguageId, cancellationToken); - if (codeGenerationPackage is not null) + if (codeGenerationPackage is not null && + !integrations.Any(integration => + integration.Name.Equals(codeGenerationPackage, StringComparison.OrdinalIgnoreCase))) { // Match sdk generate: repository mode uses the generator from this checkout, while // installed CLIs restore the package that accompanies their build. diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 6d5ffa34fa6..84f66d6101a 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -454,7 +454,9 @@ internal TypeScriptApiModel BuildApiModel( continue; } - items.Add(ProjectEntryPoint(package, entryPoint)); + var (item, declaration) = ProjectEntryPoint(entryPoint); + items.Add(item); + declarations[declaration.Id] = declaration; } foreach (var enumType in _resolved.Context.EnumTypes @@ -882,13 +884,12 @@ private TypeScriptApiMember ProjectProperty( }; } - private TypeScriptApiItem ProjectEntryPoint(TypeScriptApiPackageIdentity package, AtsCapabilityInfo capability) + private (TypeScriptApiItem Item, TypeScriptApiDeclaration Declaration) ProjectEntryPoint(AtsCapabilityInfo capability) { - _ = package; var signature = ResolveEntryPointSignature(capability); var owningAssemblyName = GetCapabilityOwningAssemblyName(capability); - return new TypeScriptApiItem + var item = new TypeScriptApiItem { Id = $"entrypoint:{owningAssemblyName}:{signature.MethodName}", TypeId = capability.CapabilityId, @@ -900,6 +901,13 @@ private TypeScriptApiItem ProjectEntryPoint(TypeScriptApiPackageIdentity package Remarks = capability.Documentation?.Remarks, Members = [] }; + + return (item, new TypeScriptApiDeclaration + { + Id = $"{owningAssemblyName}:entrypoint:{signature.MethodName}", + Content = $"export {item.Declaration};", + OwningAssemblyName = owningAssemblyName + }); } /// diff --git a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs index a187329cca7..40d523e8091 100644 --- a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs +++ b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs @@ -178,20 +178,29 @@ private static bool TryGetPackageIdentityFromAssetPath( [NotNullWhen(true)] out string? packageId, [NotNullWhen(true)] out string? packageVersion) { - // NuGet's global-packages layout is: + // NuGet managed assets use either: // ///lib|ref// + // ///runtimes//lib// // Matching from the assembly upward keeps this export-only lookup independent of the // configured global-packages root without guessing across unrelated restored packages. var targetFrameworkDirectory = Directory.GetParent(assemblyPath); var assetKindDirectory = targetFrameworkDirectory?.Parent; + var isLibAsset = string.Equals(assetKindDirectory?.Name, "lib", StringComparison.OrdinalIgnoreCase); + var isRefAsset = string.Equals(assetKindDirectory?.Name, "ref", StringComparison.OrdinalIgnoreCase); var versionDirectory = assetKindDirectory?.Parent; + if (isLibAsset && + versionDirectory?.Parent is { } runtimesDirectory && + string.Equals(runtimesDirectory.Name, "runtimes", StringComparison.OrdinalIgnoreCase)) + { + versionDirectory = runtimesDirectory.Parent; + } + var packageDirectory = versionDirectory?.Parent; if (assetKindDirectory is null || versionDirectory is null || packageDirectory is null || - (!string.Equals(assetKindDirectory.Name, "lib", StringComparison.OrdinalIgnoreCase) && - !string.Equals(assetKindDirectory.Name, "ref", StringComparison.OrdinalIgnoreCase))) + (!isLibAsset && !isRefAsset)) { packageId = null; packageVersion = null; diff --git a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs index ddbcbec9432..ba9bba3b927 100644 --- a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs +++ b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs @@ -12,6 +12,9 @@ namespace Aspire.TypeSystem; /// types. That closure is exactly why exists: it lets the exporter /// tell apart symbols the package owns and should document from symbols it merely needs to emit so the /// output is self-contained. Without it, every package would republish its dependencies' API reference. +/// +/// The constructor snapshots the assembly-name collection. Exporters should compare these CLR +/// assembly simple names using . /// public sealed class ApiReferenceExportOptions { @@ -30,7 +33,8 @@ public sealed class ApiReferenceExportOptions /// /// /// Thrown when or is empty or - /// consists only of white-space characters. + /// consists only of white-space characters, or when + /// is empty. /// public ApiReferenceExportOptions( string packageName, @@ -40,10 +44,14 @@ public ApiReferenceExportOptions( ArgumentException.ThrowIfNullOrWhiteSpace(packageName); ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); ArgumentNullException.ThrowIfNull(exportingAssemblyNames); + if (exportingAssemblyNames.Count == 0) + { + throw new ArgumentException("At least one exporting assembly name is required.", nameof(exportingAssemblyNames)); + } PackageName = packageName; PackageVersion = packageVersion; - ExportingAssemblyNames = exportingAssemblyNames; + ExportingAssemblyNames = exportingAssemblyNames.ToArray(); } /// @@ -69,5 +77,8 @@ public ApiReferenceExportOptions( /// /// Gets the assemblies whose symbols this package owns and documents. /// + /// + /// The collection is a snapshot of the names passed to the constructor. + /// public IReadOnlyCollection ExportingAssemblyNames { get; } } diff --git a/src/Aspire.TypeSystem/IApiReferenceExporter.cs b/src/Aspire.TypeSystem/IApiReferenceExporter.cs index ca88166281f..cc925d408e9 100644 --- a/src/Aspire.TypeSystem/IApiReferenceExporter.cs +++ b/src/Aspire.TypeSystem/IApiReferenceExporter.cs @@ -37,7 +37,20 @@ public interface IApiReferenceExporter /// The ATS context containing capabilities, types, and enums. /// The package identity and ownership scope for the export. /// A token to cancel the export between projected items. - /// A language-defined JSON document describing the generated API. + /// + /// A language-defined JSON document describing the generated API. The returned element must be + /// detached from any owning , for example by calling + /// . + /// + /// + /// Thrown when requests cancellation. + /// + /// + /// + /// using var document = JsonDocument.Parse(json); + /// return document.RootElement.Clone(); + /// + /// JsonElement ExportApi( AtsContext context, ApiReferenceExportOptions options, diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 55882cad276..125ef7d744e 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -91,6 +91,28 @@ public async Task SdkExportRestoresExactPackageAndWritesOnlyJsonToStdout() message => (message.ConsoleOverride ?? interactionService.Console) == ConsoleOutput.Standard); } + [Fact] + public async Task SdkExportDoesNotAddTheRequestedGeneratorPackageTwice() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider( + interactionService, + out var workspace, + out _, + out var project); + using var workspaceLease = workspace; + + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package Aspire.Hosting.CodeGeneration.TypeScript@2.0.0"); + + Assert.Equal(CliExitCodes.Success, exitCode); + var package = Assert.Single( + project.Integrations, + integration => integration.Name == "Aspire.Hosting.CodeGeneration.TypeScript"); + Assert.Equal("[2.0.0]", package.Version); + } + [Fact] public async Task SdkExportDefaultsToCoreAtTheRunningSdkVersion() { diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 25c685c198e..ed58e378652 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2000,14 +2000,37 @@ public void ApiReferenceExporterRequiresAndHonorsCancellation() cancellation.Token)); } + [Fact] + public void ApiReferenceExportOptionsCopiesExportingAssemblyNames() + { + var exportingAssemblyNames = new List { ApiExportPackageName }; + var options = new ApiReferenceExportOptions( + ApiExportPackageName, + ApiExportPackageVersion, + exportingAssemblyNames); + + exportingAssemblyNames.Clear(); + + Assert.Equal(ApiExportPackageName, Assert.Single(options.ExportingAssemblyNames)); + } + + [Fact] + public void ApiReferenceExportOptionsRequiresAnExportingAssembly() + { + Assert.Throws(() => new ApiReferenceExportOptions( + ApiExportPackageName, + ApiExportPackageVersion, + [])); + } + [Fact] public void ApiExportEntrypointIdsIncludeTheOwningAssembly() { const string firstPackage = "Aspire.Hosting.Contoso.EntryPoints"; const string secondPackage = "Aspire.Hosting.Fabrikam.EntryPoints"; - var first = Assert.Single(ProjectApi(CreateEntryPointContext(firstPackage), firstPackage) - .Modules.SelectMany(module => module.Items)); + var firstModel = ProjectApi(CreateEntryPointContext(firstPackage), firstPackage); + var first = Assert.Single(firstModel.Modules.SelectMany(module => module.Items)); var second = Assert.Single(ProjectApi(CreateEntryPointContext(secondPackage), secondPackage) .Modules.SelectMany(module => module.Items)); @@ -2017,6 +2040,12 @@ public void ApiExportEntrypointIdsIncludeTheOwningAssembly() Assert.Equal( "function startThing(client: AspireClientRpc, name: string, retries?: number): Promise", first.Declaration); + var declaration = Assert.Single( + firstModel.Declarations, + declaration => declaration.Id == $"{firstPackage}:entrypoint:startThing"); + Assert.Equal( + "export function startThing(client: AspireClientRpc, name: string, retries?: number): Promise;", + declaration.Content); var generatedSource = new AtsTypeScriptCodeGenerator() .GenerateDistributedApplication(CreateEntryPointContext(firstPackage))["aspire.mts"]; diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index ee46d4da0b9..66c3d941644 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -109,7 +109,9 @@ public void ExportApi_UsesGlobalPackagesPathsForRequestedPackage() var yarpAssemblyPath = CopyPackageAssembly( typeof(Yarp.YarpResource).Assembly.Location, packageAssetsPath, - "REF", + "runtimes", + "test-rid", + "lib", "NET8.0"); WriteProbeManifest( @@ -277,10 +279,9 @@ private static void WriteProbeManifest(string manifestPath, IEnumerable? private static string CopyPackageAssembly( string assemblyPath, string packageAssetsPath, - string assetKind, - string targetFramework) + params string[] assetPathSegments) { - var destinationDirectory = Path.Combine(packageAssetsPath, assetKind, targetFramework); + var destinationDirectory = Path.Combine([packageAssetsPath, .. assetPathSegments]); Directory.CreateDirectory(destinationDirectory); var destinationPath = Path.Combine(destinationDirectory, Path.GetFileName(assemblyPath)); File.Copy(assemblyPath, destinationPath); From c5f87c614be6c1292efc772df48dcc13f8e588bf Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 17:16:13 -0400 Subject: [PATCH 57/73] Tighten API export contracts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c235246b-d021-4d8e-b041-cc4984674ebe --- .../TypeScriptApiProjector.cs | 2 +- .../ApiReferenceExportOptions.cs | 13 +++++++--- .../IApiReferenceExporter.cs | 6 ++++- .../AtsTypeScriptCodeGeneratorTests.cs | 26 ++++++++++++++++++- .../CodeGeneration/ApiReferenceExportTests.cs | 6 ++--- 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index 84f66d6101a..d9eaa74e204 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -905,7 +905,7 @@ private TypeScriptApiMember ProjectProperty( return (item, new TypeScriptApiDeclaration { Id = $"{owningAssemblyName}:entrypoint:{signature.MethodName}", - Content = $"export {item.Declaration};", + Content = $"export declare {item.Declaration};", OwningAssemblyName = owningAssemblyName }); } diff --git a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs index ba9bba3b927..3d7ebdec1e5 100644 --- a/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs +++ b/src/Aspire.TypeSystem/ApiReferenceExportOptions.cs @@ -7,14 +7,17 @@ namespace Aspire.TypeSystem; /// Describes the package identity and ownership scope of an export. /// /// +/// /// The ATS context handed to an exporter is already filtered to the exporting assemblies, their /// reference closure, and the reduced member shapes needed to resolve wrappers for referenced handle /// types. That closure is exactly why exists: it lets the exporter /// tell apart symbols the package owns and should document from symbols it merely needs to emit so the /// output is self-contained. Without it, every package would republish its dependencies' API reference. -/// +/// +/// /// The constructor snapshots the assembly-name collection. Exporters should compare these CLR /// assembly simple names using . +/// /// public sealed class ApiReferenceExportOptions { @@ -34,7 +37,7 @@ public sealed class ApiReferenceExportOptions /// /// Thrown when or is empty or /// consists only of white-space characters, or when - /// is empty. + /// is empty or contains a null, empty, or white-space assembly name. /// public ApiReferenceExportOptions( string packageName, @@ -48,10 +51,14 @@ public ApiReferenceExportOptions( { throw new ArgumentException("At least one exporting assembly name is required.", nameof(exportingAssemblyNames)); } + if (exportingAssemblyNames.Any(string.IsNullOrWhiteSpace)) + { + throw new ArgumentException("Exporting assembly names cannot be null or white-space.", nameof(exportingAssemblyNames)); + } PackageName = packageName; PackageVersion = packageVersion; - ExportingAssemblyNames = exportingAssemblyNames.ToArray(); + ExportingAssemblyNames = Array.AsReadOnly(exportingAssemblyNames.ToArray()); } /// diff --git a/src/Aspire.TypeSystem/IApiReferenceExporter.cs b/src/Aspire.TypeSystem/IApiReferenceExporter.cs index cc925d408e9..e2636e3c8b4 100644 --- a/src/Aspire.TypeSystem/IApiReferenceExporter.cs +++ b/src/Aspire.TypeSystem/IApiReferenceExporter.cs @@ -35,7 +35,11 @@ public interface IApiReferenceExporter /// Exports the API reference for the surface the generator would produce from the same context. /// /// The ATS context containing capabilities, types, and enums. - /// The package identity and ownership scope for the export. + /// + /// The package identity and ownership scope for the export. Assembly ownership matching follows + /// the case-insensitive contract documented by + /// . + /// /// A token to cancel the export between projected items. /// /// A language-defined JSON document describing the generated API. The returned element must be diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index ed58e378652..8e9f73faf47 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2014,6 +2014,18 @@ public void ApiReferenceExportOptionsCopiesExportingAssemblyNames() Assert.Equal(ApiExportPackageName, Assert.Single(options.ExportingAssemblyNames)); } + [Fact] + public void ApiReferenceExportOptionsExposesReadOnlyExportingAssemblyNames() + { + var options = new ApiReferenceExportOptions( + ApiExportPackageName, + ApiExportPackageVersion, + [ApiExportPackageName]); + var exportingAssemblyNames = Assert.IsAssignableFrom>(options.ExportingAssemblyNames); + + Assert.Throws(() => exportingAssemblyNames[0] = "Changed"); + } + [Fact] public void ApiReferenceExportOptionsRequiresAnExportingAssembly() { @@ -2023,6 +2035,18 @@ public void ApiReferenceExportOptionsRequiresAnExportingAssembly() [])); } + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void ApiReferenceExportOptionsRequiresValidExportingAssemblyNames(string? exportingAssemblyName) + { + Assert.Throws(() => new ApiReferenceExportOptions( + ApiExportPackageName, + ApiExportPackageVersion, + [exportingAssemblyName!])); + } + [Fact] public void ApiExportEntrypointIdsIncludeTheOwningAssembly() { @@ -2044,7 +2068,7 @@ public void ApiExportEntrypointIdsIncludeTheOwningAssembly() firstModel.Declarations, declaration => declaration.Id == $"{firstPackage}:entrypoint:startThing"); Assert.Equal( - "export function startThing(client: AspireClientRpc, name: string, retries?: number): Promise;", + "export declare function startThing(client: AspireClientRpc, name: string, retries?: number): Promise;", declaration.Content); var generatedSource = new AtsTypeScriptCodeGenerator() diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index 66c3d941644..d00fed4938b 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -104,14 +104,14 @@ public void ExportApi_UsesGlobalPackagesPathsForRequestedPackage() var hostingAssemblyPath = CopyPackageAssembly( typeof(IDistributedApplicationBuilder).Assembly.Location, packageAssetsPath, + "runtimes", + "test-rid", "lib", "net8.0"); var yarpAssemblyPath = CopyPackageAssembly( typeof(Yarp.YarpResource).Assembly.Location, packageAssetsPath, - "runtimes", - "test-rid", - "lib", + "REF", "NET8.0"); WriteProbeManifest( From 5676f20db23b109eedd811f095d5ab05628d508d Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 17:51:13 -0400 Subject: [PATCH 58/73] Fix empty union projection test Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c235246b-d021-4d8e-b041-cc4984674ebe --- .../AtsTypeScriptCodeGeneratorTests.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 8e9f73faf47..7aa1342eb23 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -776,9 +776,7 @@ public void AspireUnion_InterfaceHandleInput_GeneratesExpandedUnion() [Fact] public void MapInputUnionTypeToTypeScript_ThrowsOnEmptyUnion() { - var method = typeof(AtsTypeScriptCodeGenerator).GetMethod("MapInputUnionTypeToTypeScript", BindingFlags.Instance | BindingFlags.NonPublic); - Assert.NotNull(method); - + var projector = new TypeScriptApiProjector(CreateContextFromTestAssembly()); var typeRef = new AtsTypeRef { TypeId = "test/EmptyUnion", @@ -786,9 +784,8 @@ public void MapInputUnionTypeToTypeScript_ThrowsOnEmptyUnion() UnionTypes = [], }; - var ex = Assert.Throws(() => method.Invoke(_generator, [typeRef])); - Assert.IsType(ex.InnerException); - Assert.Equal("Union input types must define at least one member type.", ex.InnerException.Message); + var ex = Assert.Throws(() => projector.MapInputUnionTypeToTypeScript(typeRef)); + Assert.Equal("Union input types must define at least one member type.", ex.Message); } [Fact] From 37fe7319c8992e0f5143b1e9b13704b64c6c8e70 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 18:24:32 -0400 Subject: [PATCH 59/73] Fix exact package restore with CPM Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c235246b-d021-4d8e-b041-cc4984674ebe --- src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs | 2 +- tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index 0310505326a..89c89f54cfb 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -223,7 +223,7 @@ private XDocument CreateProjectFile(IEnumerable integratio doc.Root!.Add(new XElement("ItemGroup", otherPackages.Select(p => new XElement("PackageReference", new XAttribute("Include", p.Name), - new XAttribute("Version", p.Version))))); + new XAttribute("VersionOverride", p.Version))))); } // Add imports for in-repo AppHost building diff --git a/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs b/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs index 44b61a92264..96807c43886 100644 --- a/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs @@ -194,7 +194,8 @@ public async Task CreateProjectFiles_ExactAspirePackageRestoresInsteadOfUsingChe document.Descendants("PackageReference"), element => element.Attribute("Include")?.Value == "Aspire.Hosting.Redis"); - Assert.Equal("[13.1.0]", packageReference.Attribute("Version")?.Value); + Assert.Equal("[13.1.0]", packageReference.Attribute("VersionOverride")?.Value); + Assert.Null(packageReference.Attribute("Version")); Assert.DoesNotContain( document.Descendants("PackageReference"), element => element.Attribute("Include")?.Value == "Aspire.Hosting.PostgreSQL"); From c7fd567eea3d4942c6f09dcd78b1d6c56aa09b4f Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 22:57:40 -0400 Subject: [PATCH 60/73] Fix canonical package identity in SDK exports Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3253974d-4f18-486f-863c-281a607656d4 --- .../Projects/AppHostServerClosureSnapshots.cs | 3 ++- .../AssemblyLoader.cs | 18 ++++++++++++++++-- .../CodeGeneration/CodeGenerationService.cs | 5 +++-- src/Shared/IntegrationPackageProbeManifest.cs | 17 +++++++++++++++-- .../Projects/PrebuiltAppHostServerTests.cs | 1 + .../CodeGeneration/ApiReferenceExportTests.cs | 8 +++++--- 6 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs index 9f40442407e..a8d00a659e2 100644 --- a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs +++ b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs @@ -171,7 +171,8 @@ public IntegrationPackageProbeManifest CreatePackageProbeManifest() { Name = Path.GetFileNameWithoutExtension(entry.RelativePath), Culture = TryGetSatelliteCulture(entry), - Path = entry.SourcePath + Path = entry.SourcePath, + PackageId = entry.PackageId }); } diff --git a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs index 40d523e8091..c22db93d1dd 100644 --- a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs +++ b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs @@ -73,12 +73,14 @@ public IReadOnlyList GetAssemblies() public bool TryGetPackageAssemblyNamesFromProbePaths( string packageId, string packageVersion, - out IReadOnlyList assemblyNames) + out IReadOnlyList assemblyNames, + [NotNullWhen(true)] out string? canonicalPackageId) { ArgumentException.ThrowIfNullOrWhiteSpace(packageId); ArgumentException.ThrowIfNullOrWhiteSpace(packageVersion); var names = new SortedSet(StringComparer.OrdinalIgnoreCase); + canonicalPackageId = null; foreach (var assembly in _packageProbeManifest.ManagedAssemblies) { @@ -90,11 +92,23 @@ public bool TryGetPackageAssemblyNamesFromProbePaths( continue; } + if (assembly.PackageId is not null && + string.Equals(assembly.PackageId, packageId, StringComparison.OrdinalIgnoreCase)) + { + canonicalPackageId ??= assembly.PackageId; + } + names.Add(assembly.Name); } assemblyNames = names.ToList(); - return assemblyNames.Count > 0; + if (assemblyNames.Count == 0) + { + return false; + } + + canonicalPackageId ??= packageId; + return true; } /// diff --git a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs index 39f00a86c2c..286420e64f3 100644 --- a/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs +++ b/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs @@ -382,7 +382,8 @@ private IReadOnlyList ResolvePackageExportingAssemblyNames( if (_assemblyLoader.TryGetPackageAssemblyNamesFromProbePaths( packageName, packageVersion, - out var manifestAssemblyNames)) + out var manifestAssemblyNames, + out var manifestPackageName)) { var exportingAssemblyNames = new List(manifestAssemblyNames.Count); foreach (var assemblyName in manifestAssemblyNames) @@ -400,7 +401,7 @@ private IReadOnlyList ResolvePackageExportingAssemblyNames( "but none of its assemblies reached the scanned API surface."); } - canonicalPackageName = packageName; + canonicalPackageName = manifestPackageName; return exportingAssemblyNames; } diff --git a/src/Shared/IntegrationPackageProbeManifest.cs b/src/Shared/IntegrationPackageProbeManifest.cs index 24b8fa64743..aadbac93e52 100644 --- a/src/Shared/IntegrationPackageProbeManifest.cs +++ b/src/Shared/IntegrationPackageProbeManifest.cs @@ -50,7 +50,8 @@ public static IntegrationPackageProbeManifest Create( { Name = NormalizeRequiredValue(assembly.Name, "managedAssemblies[].name"), Culture = NormalizeCulture(assembly.Culture), - Path = NormalizeRequiredValue(assembly.Path, "managedAssemblies[].path") + Path = NormalizeRequiredValue(assembly.Path, "managedAssemblies[].path"), + PackageId = NormalizeOptionalValue(assembly.PackageId) }; managedLookup.TryAdd( @@ -142,6 +143,10 @@ public static Task WriteAsync( { writer.WriteString("culture", managedAssembly.Culture); } + if (managedAssembly.PackageId is not null) + { + writer.WriteString("packageId", managedAssembly.PackageId); + } writer.WriteString("path", managedAssembly.Path); writer.WriteEndObject(); } @@ -370,6 +375,11 @@ private static string NormalizeRequiredValue(string? value, string propertyName) return value.Trim(); } + private static string? NormalizeOptionalValue(string? value) + { + return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); + } + private static IReadOnlyList ReadManagedAssemblies(JsonElement rootElement) { if (!rootElement.TryGetProperty("managedAssemblies", out var managedAssembliesElement) || @@ -385,7 +395,8 @@ private static IReadOnlyList ReadManagedAssem { Name = NormalizeRequiredValue(ReadStringProperty(element, "name"), "managedAssemblies[].name"), Culture = NormalizeCulture(ReadStringProperty(element, "culture", required: false)), - Path = NormalizeAndValidatePath(ReadStringProperty(element, "path"), "managedAssemblies[].path") + Path = NormalizeAndValidatePath(ReadStringProperty(element, "path"), "managedAssemblies[].path"), + PackageId = NormalizeOptionalValue(ReadStringProperty(element, "packageId", required: false)) }); } @@ -445,6 +456,8 @@ internal sealed class IntegrationPackageManagedAssembly public string? Culture { get; init; } public required string Path { get; init; } + + public string? PackageId { get; init; } } /// diff --git a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs index 898530cbad5..77d528d8078 100644 --- a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs @@ -2057,6 +2057,7 @@ public async Task PrepareAsync_WithProjectReferences_WritesPackageProbeManifestA Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Aspire.Hosting.Redis" && + assembly.GetProperty("packageId").GetString() == "Aspire.Hosting.Redis" && assembly.GetProperty("path").GetString() == Path.Combine(workingDirectory, "integration-restore", "closure-sources", "Aspire.Hosting.Redis.dll")); Assert.Equal(0, probeManifest.RootElement.GetProperty("nativeLibraries").GetArrayLength()); } diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs index d00fed4938b..a8a9593518b 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/CodeGeneration/ApiReferenceExportTests.cs @@ -121,12 +121,14 @@ public void ExportApi_UsesGlobalPackagesPathsForRequestedPackage() new { Name = "Aspire.Hosting", - Path = hostingAssemblyPath + Path = hostingAssemblyPath, + PackageId = "Contoso.Aspire.MetaPackage" }, new { Name = "Aspire.Hosting.Yarp", - Path = yarpAssemblyPath + Path = yarpAssemblyPath, + PackageId = "Contoso.Aspire.MetaPackage" } ]); var service = CreateCodeGenerationService(new Dictionary @@ -138,7 +140,7 @@ public void ExportApi_UsesGlobalPackagesPathsForRequestedPackage() () => service.ExportApi("TypeScript", "Contoso.Aspire.MetaPackage", "9.9.9", CancellationToken.None)); Assert.Contains("9.9.9", versionMismatch.Message, StringComparison.Ordinal); - var export = service.ExportApi("TypeScript", "Contoso.Aspire.MetaPackage", "1.2.3", CancellationToken.None); + var export = service.ExportApi("TypeScript", "contoso.aspire.metapackage", "1.2.3", CancellationToken.None); Assert.Equal("Contoso.Aspire.MetaPackage", export.GetProperty("package").GetProperty("name").GetString()); From dc14f2eb32d8bb9d994d524ca901362f4e6d0cb1 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 10 Aug 2026 23:07:04 -0400 Subject: [PATCH 61/73] Accept four-part NuGet versions in SDK export Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3253974d-4f18-486f-863c-281a607656d4 --- .../Commands/Sdk/SdkExportCommand.cs | 35 +++++++++++++++++-- .../Commands/Sdk/SdkExportCommandTests.cs | 24 +++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 421b1d01670..6bb5be52bc6 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -267,14 +267,22 @@ private static bool TryParsePackage( return false; } - if (requestedVersion.Any(char.IsWhiteSpace) || - !SemVersion.TryParse(requestedVersion, SemVersionStyles.Any, out var parsedVersion)) + if (requestedVersion.Any(char.IsWhiteSpace)) + { + errorMessage = $"Invalid version '{requestedVersion}'. Expected an exact NuGet version."; + return false; + } + + if (SemVersion.TryParse(requestedVersion, SemVersionStyles.Any, out var parsedVersion)) + { + packageVersion = parsedVersion.ToString(); + } + else if (!TryNormalizeFourPartVersion(requestedVersion, out packageVersion)) { errorMessage = $"Invalid version '{requestedVersion}'. Expected an exact NuGet version."; return false; } - packageVersion = parsedVersion.ToString(); var buildMetadataIndex = packageVersion.IndexOf('+', StringComparison.Ordinal); if (buildMetadataIndex >= 0) { @@ -283,4 +291,25 @@ private static bool TryParsePackage( return true; } + + private static bool TryNormalizeFourPartVersion(string version, out string normalizedVersion) + { + normalizedVersion = string.Empty; + + // NuGet accepts a four-component numeric version that SemVer does not: + // 1.2.3.4 + // Keep SemVersion as the primary parser so ordinary versions and prerelease labels retain + // their existing normalization, then narrowly fall back to System.Version for this shape. + var components = version.Split('.'); + if (components.Length != 4 || + components.Any(static component => + component.Length == 0 || component.Any(static character => !char.IsAsciiDigit(character))) || + !Version.TryParse(version, out var parsedVersion)) + { + return false; + } + + normalizedVersion = parsedVersion.ToString(4); + return true; + } } diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 125ef7d744e..2d7f9521502 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -91,6 +91,30 @@ public async Task SdkExportRestoresExactPackageAndWritesOnlyJsonToStdout() message => (message.ConsoleOverride ?? interactionService.Console) == ConsoleOutput.Standard); } + [Fact] + public async Task SdkExportRestoresNormalizedFourPartNuGetVersion() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider( + interactionService, + out var workspace, + out var rpcClient, + out var project); + using var workspaceLease = workspace; + + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package Contoso.Aspire.Widgets@1.2.3.4"); + + Assert.Equal(CliExitCodes.Success, exitCode); + Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "1.2.3.4"), rpcClient.LastExportRequest); + + var package = Assert.Single( + project.Integrations, + integration => integration.Name == "Contoso.Aspire.Widgets"); + Assert.Equal("[1.2.3.4]", package.Version); + } + [Fact] public async Task SdkExportDoesNotAddTheRequestedGeneratorPackageTwice() { From 6a279f74449ee83e4c0c27fa80ca33ac5c01dd20 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Tue, 11 Aug 2026 00:34:14 -0400 Subject: [PATCH 62/73] Propagate canonical package IDs in probe manifests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3253974d-4f18-486f-863c-281a607656d4 --- .../NuGet/Commands/ManifestCommand.cs | 1 + .../Commands/NuGetPackageAssetResolver.cs | 33 ++++++++++++------- .../LayoutCommandTests.cs | 5 +-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs index a027af5a608..37f13ae9bb7 100644 --- a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs +++ b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs @@ -136,6 +136,7 @@ internal static IntegrationPackageProbeManifest CreateManifest(IEnumerable Assets, int SkippedCount) Resol // Synthetic restores can leave the base lib assembly in the target even when the package // contains a compatible portable runtime asset. Prefer the runtime asset for probing. var runtimeAssemblyOverrides = GetRuntimeAssemblyOverrides(packageLibrary, targetFramework, runtimeIdentifiers); - AddRuntimeAssemblies(assets, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides); - AddRuntimeTargets(assets, library.RuntimeTargets, packagePath); - AddResourceAssemblies(assets, library.ResourceAssemblies, packagePath); - AddNativeLibraries(assets, library.NativeLibraries, packagePath); + AddRuntimeAssemblies(assets, libraryName, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides); + AddRuntimeTargets(assets, libraryName, library.RuntimeTargets, packagePath); + AddResourceAssemblies(assets, libraryName, library.ResourceAssemblies, packagePath); + AddNativeLibraries(assets, libraryName, library.NativeLibraries, packagePath); return (assets, 0); } private static void AddRuntimeAssemblies( List assets, + string packageId, IEnumerable runtimeAssemblies, string packagePath, IReadOnlyDictionary runtimeAssemblyOverrides) @@ -176,16 +179,17 @@ private static void AddRuntimeAssemblies( if (!relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase) && runtimeAssemblyOverrides.TryGetValue(GetFileName(relativePath), out var overridePath)) { - AddRuntimeAssembly(assets, packagePath, overridePath); + AddRuntimeAssembly(assets, packageId, packagePath, overridePath); continue; } - AddRuntimeAssembly(assets, packagePath, relativePath); + AddRuntimeAssembly(assets, packageId, packagePath, relativePath); } } private static void AddRuntimeAssembly( List assets, + string packageId, string packagePath, string relativePath) { @@ -196,17 +200,17 @@ private static void AddRuntimeAssembly( } var fileName = Path.GetFileName(sourcePath); - AddAsset(assets, sourcePath, fileName, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); + AddAsset(assets, packageId, sourcePath, fileName, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); if (relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase)) { - AddAsset(assets, sourcePath, relativePath, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); + AddAsset(assets, packageId, sourcePath, relativePath, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); } var xmlSourcePath = Path.ChangeExtension(sourcePath, ".xml"); if (File.Exists(xmlSourcePath)) { - AddAsset(assets, xmlSourcePath, Path.ChangeExtension(fileName, ".xml"), isManagedAssembly: false, isNativeLibrary: false); + AddAsset(assets, packageId, xmlSourcePath, Path.ChangeExtension(fileName, ".xml"), isManagedAssembly: false, isNativeLibrary: false); } } @@ -309,6 +313,7 @@ private static string GetFileName(string path) private static void AddRuntimeTargets( List assets, + string packageId, IEnumerable runtimeTargets, string packagePath) { @@ -327,6 +332,7 @@ private static void AddRuntimeTargets( AddAsset( assets, + packageId, sourcePath, runtimeTarget.Path, isManagedAssembly: string.Equals(runtimeTarget.AssetType, "runtime", StringComparison.OrdinalIgnoreCase) && IsManagedAssembly(sourcePath), @@ -336,6 +342,7 @@ private static void AddRuntimeTargets( private static void AddResourceAssemblies( List assets, + string packageId, IEnumerable resourceAssemblies, string packagePath) { @@ -363,6 +370,7 @@ private static void AddResourceAssemblies( AddAsset( assets, + packageId, sourcePath, Path.Combine(locale, Path.GetFileName(sourcePath)), isManagedAssembly: IsManagedAssembly(sourcePath), @@ -373,6 +381,7 @@ private static void AddResourceAssemblies( private static void AddNativeLibraries( List assets, + string packageId, IEnumerable nativeLibraries, string packagePath) { @@ -389,13 +398,14 @@ private static void AddNativeLibraries( continue; } - AddAsset(assets, sourcePath, Path.GetFileName(sourcePath), isManagedAssembly: false, isNativeLibrary: true); - AddAsset(assets, sourcePath, nativeLib.Path, isManagedAssembly: false, isNativeLibrary: true); + AddAsset(assets, packageId, sourcePath, Path.GetFileName(sourcePath), isManagedAssembly: false, isNativeLibrary: true); + AddAsset(assets, packageId, sourcePath, nativeLib.Path, isManagedAssembly: false, isNativeLibrary: true); } } private static void AddAsset( List assets, + string packageId, string sourcePath, string relativePath, bool isManagedAssembly, @@ -404,6 +414,7 @@ private static void AddAsset( { assets.Add(new NuGetPackageAsset { + PackageId = packageId, SourcePath = sourcePath, RelativePath = NormalizeRelativePath(relativePath), IsManagedAssembly = isManagedAssembly, diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs index 4fbef60dd61..c0a59739aae 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/LayoutCommandTests.cs @@ -211,7 +211,7 @@ public async Task ManifestCommand_WritesPackageProbeManifestWithoutCreatingLibsL } [Fact] - public async Task RestoreAndManifestCommands_WritePackageCacheManifestWithoutCreatingLibsLayout() + public async Task RestoreAndManifestCommands_WriteCanonicalPackageIdFromLowercaseRequest() { var workspaceRoot = Directory.CreateTempSubdirectory("aspire-restore-manifest-tests").FullName; @@ -228,7 +228,7 @@ public async Task RestoreAndManifestCommands_WritePackageCacheManifestWithoutCre var objPath = Path.Combine(workspaceRoot, "restore", "obj"); var restoreCommand = RestoreCommand.Create(); var restoreParseResult = restoreCommand.Parse([ - "--package", "Test.Package,1.0.0", + "--package", "test.package,1.0.0", "--framework", "net10.0", "--output", objPath, "--source", sourcePath, @@ -261,6 +261,7 @@ public async Task RestoreAndManifestCommands_WritePackageCacheManifestWithoutCre Assert.Contains( managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Test.Package" && + assembly.GetProperty("packageId").GetString() == "Test.Package" && assembly.GetProperty("path").GetString() == expectedAssemblyPath); Assert.DoesNotContain( managedAssemblies, From 0c56951f4b22e0a4a2edee89b0a9e6f9543e0219 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Tue, 11 Aug 2026 00:40:57 -0400 Subject: [PATCH 63/73] Normalize zero NuGet version revisions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3253974d-4f18-486f-863c-281a607656d4 --- src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs | 4 +++- .../Commands/Sdk/SdkExportCommandTests.cs | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 6bb5be52bc6..64f41271e57 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -309,7 +309,9 @@ private static bool TryNormalizeFourPartVersion(string version, out string norma return false; } - normalizedVersion = parsedVersion.ToString(4); + normalizedVersion = parsedVersion.Revision == 0 + ? parsedVersion.ToString(3) + : parsedVersion.ToString(4); return true; } } diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 2d7f9521502..ff2d5040273 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -91,8 +91,10 @@ public async Task SdkExportRestoresExactPackageAndWritesOnlyJsonToStdout() message => (message.ConsoleOverride ?? interactionService.Console) == ConsoleOutput.Standard); } - [Fact] - public async Task SdkExportRestoresNormalizedFourPartNuGetVersion() + [Theory] + [InlineData("1.2.3.4", "1.2.3.4")] + [InlineData("1.2.3.0", "1.2.3")] + public async Task SdkExportRestoresNormalizedFourPartNuGetVersion(string requestedVersion, string normalizedVersion) { var interactionService = new TestInteractionService(); using var provider = CreateProvider( @@ -104,15 +106,15 @@ public async Task SdkExportRestoresNormalizedFourPartNuGetVersion() var exitCode = await InvokeAsync( provider, - "sdk export --language typescript --package Contoso.Aspire.Widgets@1.2.3.4"); + $"sdk export --language typescript --package Contoso.Aspire.Widgets@{requestedVersion}"); Assert.Equal(CliExitCodes.Success, exitCode); - Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", "1.2.3.4"), rpcClient.LastExportRequest); + Assert.Equal(("TypeScript", "Contoso.Aspire.Widgets", normalizedVersion), rpcClient.LastExportRequest); var package = Assert.Single( project.Integrations, integration => integration.Name == "Contoso.Aspire.Widgets"); - Assert.Equal("[1.2.3.4]", package.Version); + Assert.Equal($"[{normalizedVersion}]", package.Version); } [Fact] From 8753075b6e7012bd37dae6272a79d00dfa87959a Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 14 Aug 2026 18:43:55 -0400 Subject: [PATCH 64/73] Keep sdk export package restores explicit Preserve normal repository substitution for exact version ranges and cover the real export subprocess against the installed package hive. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d65b598f-72dd-4fca-bdc4-8debbbd7f821 --- .../Commands/Sdk/SdkExportCommand.cs | 5 +- .../Configuration/IntegrationReference.cs | 24 +++++- .../DotNetBasedAppHostServerProject.cs | 10 +-- .../SdkExportTests.cs | 82 +++++++++++++++++++ .../Commands/Sdk/SdkExportCommandTests.cs | 1 + .../Projects/AppHostServerProjectTests.cs | 32 +++++++- 6 files changed, 142 insertions(+), 12 deletions(-) create mode 100644 tests/Aspire.Cli.EndToEnd.Tests/SdkExportTests.cs diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 64f41271e57..93f793b2b43 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -236,7 +236,10 @@ private async Task ExportApiAsync( } private static IntegrationReference CreateExactPackageReference(string packageName, string packageVersion) - => IntegrationReference.FromPackage(packageName, $"[{packageVersion}]"); + => IntegrationReference.FromPackage( + packageName, + $"[{packageVersion}]", + disableLocalProjectSubstitution: true); private static bool TryParsePackage( string argument, diff --git a/src/Aspire.Cli/Configuration/IntegrationReference.cs b/src/Aspire.Cli/Configuration/IntegrationReference.cs index 79cbe97b65a..88f657179a4 100644 --- a/src/Aspire.Cli/Configuration/IntegrationReference.cs +++ b/src/Aspire.Cli/Configuration/IntegrationReference.cs @@ -24,6 +24,11 @@ internal sealed class IntegrationReference /// public string? ProjectPath { get; init; } + /// + /// Gets whether repository mode must restore this package instead of substituting a checkout project. + /// + public bool DisableLocalProjectSubstitution { get; init; } + /// /// Returns true if this is a project reference (has a .csproj path). /// @@ -40,11 +45,28 @@ internal sealed class IntegrationReference /// The package name. /// The NuGet package version. public static IntegrationReference FromPackage(string name, string version) + => FromPackage(name, version, disableLocalProjectSubstitution: false); + + /// + /// Creates a NuGet package reference. + /// + /// The package name. + /// The NuGet package version. + /// Whether repository mode must restore the package instead of substituting a checkout project. + public static IntegrationReference FromPackage( + string name, + string version, + bool disableLocalProjectSubstitution) { ArgumentException.ThrowIfNullOrEmpty(name); ArgumentException.ThrowIfNullOrEmpty(version); - return new IntegrationReference { Name = name, Version = version }; + return new IntegrationReference + { + Name = name, + Version = version, + DisableLocalProjectSubstitution = disableLocalProjectSubstitution + }; } /// diff --git a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs index 5e82f87b62e..682093d1a0c 100644 --- a/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs +++ b/src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs @@ -181,10 +181,8 @@ private XDocument CreateProjectFile(IEnumerable integratio new XElement("IsAspireProjectResource", "false"))); } } - // An exact range is an explicit request to restore that package, used by sdk export so - // the document cannot be labelled with a package version while describing checkout code. else if (integration.Name.StartsWith("Aspire.Hosting", StringComparison.OrdinalIgnoreCase) && - !IsExactVersionRange(integration.Version)) + !integration.DisableLocalProjectSubstitution) { var projectPath = Path.Combine(_repoRoot, "src", integration.Name, $"{integration.Name}.csproj"); if (File.Exists(projectPath) && addedProjects.Add(integration.Name)) @@ -261,12 +259,6 @@ private XDocument CreateProjectFile(IEnumerable integratio return doc; } - private static bool IsExactVersionRange(string? version) - => version is { Length: > 2 } && - version[0] == '[' && - version[^1] == ']' && - !version.Contains(','); - /// /// Scaffolds the project files. /// diff --git a/tests/Aspire.Cli.EndToEnd.Tests/SdkExportTests.cs b/tests/Aspire.Cli.EndToEnd.Tests/SdkExportTests.cs new file mode 100644 index 00000000000..a591183c931 --- /dev/null +++ b/tests/Aspire.Cli.EndToEnd.Tests/SdkExportTests.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text.Json; +using Aspire.Cli.EndToEnd.Tests.Helpers; +using Hex1b.Automation; +using Xunit; + +namespace Aspire.Cli.EndToEnd.Tests; + +public sealed class SdkExportTests(ITestOutputHelper output) +{ + [CaptureWorkspaceOnFailure] + [Fact] + public async Task ExportPackageFromInstalledHiveWritesJsonToStandardOutput() + { + var repoRoot = CliE2ETestHelpers.GetRepoRoot(); + var strategy = CliInstallStrategy.Detect(output.WriteLine); + Assert.SkipUnless( + strategy.Mode is CliInstallMode.LocalHive or CliInstallMode.LocalArchive or CliInstallMode.PullRequest, + "The sdk export E2E test requires a locally built package hive."); + + var workspace = TemporaryWorkspace.Create(output); + var scriptPath = Path.Combine(workspace.WorkspaceRoot.FullName, "run-sdk-export.sh"); + var exportPath = Path.Combine(workspace.WorkspaceRoot.FullName, "sdk-export.json"); + + await File.WriteAllTextAsync( + scriptPath, + """ + #!/usr/bin/env bash + set -euo pipefail + + find "$HOME/.aspire/hives" -type f -name 'Aspire.Hosting.Redis.*.nupkg' -print -quit > sdk-export-package-path.txt + read -r package_path < sdk-export-package-path.txt + test -n "$package_path" + + package_file="${package_path##*/}" + package_version="${package_file#Aspire.Hosting.Redis.}" + package_version="${package_version%.nupkg}" + export ASPIRE_CLI_PACKAGES="${package_path%/*}" + + aspire sdk export \ + --language typescript \ + --package "Aspire.Hosting.Redis@${package_version}" \ + > sdk-export.json + """, + TestContext.Current.CancellationToken); + + using var terminal = CliE2ETestHelpers.CreateDockerTestTerminal( + repoRoot, + strategy, + output, + workspace: workspace); + + var counter = new SequenceCounter(); + var auto = new Hex1bTerminalAutomator(terminal, defaultTimeout: TimeSpan.FromSeconds(500)); + await using var terminalRun = CliE2ETestHelpers.StartRun( + terminal, + workspace, + auto, + counter, + output, + TestContext.Current.CancellationToken); + + await auto.PrepareDockerEnvironmentAsync(counter, workspace); + await auto.InstallAspireCliAsync(strategy, counter); + await auto.RunCommandAsync("bash run-sdk-export.sh", counter, TimeSpan.FromMinutes(5)); + + using var document = JsonDocument.Parse(await File.ReadAllTextAsync( + exportPath, + TestContext.Current.CancellationToken)); + var root = document.RootElement; + + Assert.Equal(1, root.GetProperty("schemaVersion").GetInt32()); + Assert.Equal("typescript", root.GetProperty("language").GetString()); + Assert.Equal("Aspire.Hosting.Redis", root.GetProperty("package").GetProperty("name").GetString()); + Assert.False(string.IsNullOrWhiteSpace( + root.GetProperty("package").GetProperty("version").GetString())); + Assert.Equal(JsonValueKind.Array, root.GetProperty("modules").ValueKind); + Assert.Equal(JsonValueKind.Array, root.GetProperty("declarations").ValueKind); + } +} diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index ff2d5040273..c7197cc95d1 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -71,6 +71,7 @@ public async Task SdkExportRestoresExactPackageAndWritesOnlyJsonToStdout() project.Integrations, integration => integration.Name == "Contoso.Aspire.Widgets"); Assert.Equal("[2.0.0]", package.Version); + Assert.True(package.DisableLocalProjectSubstitution); var generator = Assert.Single( project.Integrations, diff --git a/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs b/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs index 96807c43886..f762bca6940 100644 --- a/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs @@ -183,7 +183,10 @@ public async Task CreateProjectFiles_ExactAspirePackageRestoresInsteadOfUsingChe var project = CreateProject(); var integrations = new[] { - IntegrationReference.FromPackage("Aspire.Hosting.Redis", "[13.1.0]"), + IntegrationReference.FromPackage( + "Aspire.Hosting.Redis", + "[13.1.0]", + disableLocalProjectSubstitution: true), IntegrationReference.FromPackage("Aspire.Hosting.PostgreSQL", "13.1.0") }; @@ -201,6 +204,33 @@ public async Task CreateProjectFiles_ExactAspirePackageRestoresInsteadOfUsingChe element => element.Attribute("Include")?.Value == "Aspire.Hosting.PostgreSQL"); } + [Fact] + public async Task CreateProjectFiles_ExactVersionRangeUsesCheckoutProjectByDefault() + { + var integrationDirectory = _workspace.WorkspaceRoot.CreateSubdirectory( + Path.Combine("src", "Aspire.Hosting.Redis")); + var integrationProjectPath = Path.Combine(integrationDirectory.FullName, "Aspire.Hosting.Redis.csproj"); + await File.WriteAllTextAsync(integrationProjectPath, ""); + + var project = CreateProject(); + var integrations = new[] + { + IntegrationReference.FromPackage("Aspire.Hosting.Redis", "[13.1.0]") + }; + + var (projectPath, _) = await project.CreateProjectFilesAsync(integrations).DefaultTimeout(); + + var document = XDocument.Load(projectPath); + var projectReference = Assert.Single( + document.Descendants("ProjectReference"), + element => element.Attribute("Include")?.Value == integrationProjectPath); + + Assert.Equal("false", projectReference.Element("IsAspireProjectResource")?.Value); + Assert.DoesNotContain( + document.Descendants("PackageReference"), + element => element.Attribute("Include")?.Value == "Aspire.Hosting.Redis"); + } + [Fact] public void ProjectModelPath_IsStableForSameAppPath() { From 7a628a47d3dac779ecca0980756fec9b9ebdfd1c Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 14 Aug 2026 18:58:54 -0400 Subject: [PATCH 65/73] Honor pre-canceled API exports Check cancellation before resolving the TypeScript projection and cover the ordering explicitly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d65b598f-72dd-4fca-bdc4-8debbbd7f821 --- .../AtsTypeScriptApiReferenceExporter.cs | 1 + .../AtsTypeScriptCodeGeneratorTests.cs | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs index 37d9faf387b..f0c09605c0f 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptApiReferenceExporter.cs @@ -44,6 +44,7 @@ public JsonElement ExportApi( { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(options); + cancellationToken.ThrowIfCancellationRequested(); // Build the projector from the same context the generator would use, so the exported // documentation describes the exact signatures generation would emit rather than a diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 7aa1342eb23..911b51b62be 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1987,9 +1987,17 @@ public void ApiReferenceExporterRequiresAndHonorsCancellation() using var cancellation = new CancellationTokenSource(); cancellation.Cancel(); + var context = new AtsContext + { + Capabilities = null!, + HandleTypes = [], + DtoTypes = [], + EnumTypes = [] + }; + IApiReferenceExporter exporter = new AtsTypeScriptApiReferenceExporter(); Assert.Throws(() => exporter.ExportApi( - CreateEntryPointContext(ApiExportPackageName), + context, new ApiReferenceExportOptions( ApiExportPackageName, ApiExportPackageVersion, From 59cb35ac213fddfd88b5ef77f5696ba754088d0d Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 14 Aug 2026 19:29:06 -0400 Subject: [PATCH 66/73] Fix package identity for copied integration assets Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d65b598f-72dd-4fca-bdc4-8debbbd7f821 --- .../Projects/AppHostServerClosureSnapshots.cs | 3 +- .../AssemblyLoader.cs | 31 ++++++++--- .../NuGet/Commands/ManifestCommand.cs | 1 + .../Commands/NuGetPackageAssetResolver.cs | 33 ++++++++---- src/Shared/IntegrationPackageProbeManifest.cs | 12 ++++- .../Projects/PrebuiltAppHostServerTests.cs | 1 + .../AssemblyLoaderTests.cs | 54 +++++++++++++++++++ 7 files changed, 114 insertions(+), 21 deletions(-) diff --git a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs index a8d00a659e2..cdd39722f78 100644 --- a/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs +++ b/src/Aspire.Cli/Projects/AppHostServerClosureSnapshots.cs @@ -172,7 +172,8 @@ public IntegrationPackageProbeManifest CreatePackageProbeManifest() Name = Path.GetFileNameWithoutExtension(entry.RelativePath), Culture = TryGetSatelliteCulture(entry), Path = entry.SourcePath, - PackageId = entry.PackageId + PackageId = entry.PackageId, + PackageVersion = entry.PackageVersion }); } diff --git a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs index c22db93d1dd..a9e39892e5f 100644 --- a/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs +++ b/src/Aspire.Hosting.RemoteHost/AssemblyLoader.cs @@ -84,21 +84,38 @@ public bool TryGetPackageAssemblyNamesFromProbePaths( foreach (var assembly in _packageProbeManifest.ManagedAssemblies) { - if (assembly.Culture is not null || - !TryGetPackageIdentityFromAssetPath(assembly.Path, out var pathPackageId, out var pathPackageVersion) || - !string.Equals(pathPackageId, packageId, StringComparison.OrdinalIgnoreCase) || - !string.Equals(pathPackageVersion, packageVersion, StringComparison.OrdinalIgnoreCase)) + if (assembly.Culture is not null) { continue; } if (assembly.PackageId is not null && - string.Equals(assembly.PackageId, packageId, StringComparison.OrdinalIgnoreCase)) + assembly.PackageVersion is not null) { - canonicalPackageId ??= assembly.PackageId; + if (string.Equals(assembly.PackageId, packageId, StringComparison.OrdinalIgnoreCase) && + string.Equals(assembly.PackageVersion, packageVersion, StringComparison.OrdinalIgnoreCase)) + { + canonicalPackageId ??= assembly.PackageId; + names.Add(assembly.Name); + } + + continue; } - names.Add(assembly.Name); + // Older manifests do not record package versions, so package ownership must be + // recovered from the conventional global-packages path when possible. + if (TryGetPackageIdentityFromAssetPath(assembly.Path, out var pathPackageId, out var pathPackageVersion) && + string.Equals(pathPackageId, packageId, StringComparison.OrdinalIgnoreCase) && + string.Equals(pathPackageVersion, packageVersion, StringComparison.OrdinalIgnoreCase)) + { + if (assembly.PackageId is not null && + string.Equals(assembly.PackageId, packageId, StringComparison.OrdinalIgnoreCase)) + { + canonicalPackageId ??= assembly.PackageId; + } + + names.Add(assembly.Name); + } } assemblyNames = names.ToList(); diff --git a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs index 37f13ae9bb7..b3d6bf84f17 100644 --- a/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs +++ b/src/Aspire.Managed/NuGet/Commands/ManifestCommand.cs @@ -137,6 +137,7 @@ internal static IntegrationPackageProbeManifest CreateManifest(IEnumerable Assets, int SkippedCount) Resol // Synthetic restores can leave the base lib assembly in the target even when the package // contains a compatible portable runtime asset. Prefer the runtime asset for probing. var runtimeAssemblyOverrides = GetRuntimeAssemblyOverrides(packageLibrary, targetFramework, runtimeIdentifiers); - AddRuntimeAssemblies(assets, libraryName, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides); - AddRuntimeTargets(assets, libraryName, library.RuntimeTargets, packagePath); - AddResourceAssemblies(assets, libraryName, library.ResourceAssemblies, packagePath); - AddNativeLibraries(assets, libraryName, library.NativeLibraries, packagePath); + AddRuntimeAssemblies(assets, libraryName, libraryVersion, library.RuntimeAssemblies, packagePath, runtimeAssemblyOverrides); + AddRuntimeTargets(assets, libraryName, libraryVersion, library.RuntimeTargets, packagePath); + AddResourceAssemblies(assets, libraryName, libraryVersion, library.ResourceAssemblies, packagePath); + AddNativeLibraries(assets, libraryName, libraryVersion, library.NativeLibraries, packagePath); return (assets, 0); } @@ -164,6 +166,7 @@ private static (IReadOnlyList Assets, int SkippedCount) Resol private static void AddRuntimeAssemblies( List assets, string packageId, + string packageVersion, IEnumerable runtimeAssemblies, string packagePath, IReadOnlyDictionary runtimeAssemblyOverrides) @@ -179,17 +182,18 @@ private static void AddRuntimeAssemblies( if (!relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase) && runtimeAssemblyOverrides.TryGetValue(GetFileName(relativePath), out var overridePath)) { - AddRuntimeAssembly(assets, packageId, packagePath, overridePath); + AddRuntimeAssembly(assets, packageId, packageVersion, packagePath, overridePath); continue; } - AddRuntimeAssembly(assets, packageId, packagePath, relativePath); + AddRuntimeAssembly(assets, packageId, packageVersion, packagePath, relativePath); } } private static void AddRuntimeAssembly( List assets, string packageId, + string packageVersion, string packagePath, string relativePath) { @@ -200,17 +204,17 @@ private static void AddRuntimeAssembly( } var fileName = Path.GetFileName(sourcePath); - AddAsset(assets, packageId, sourcePath, fileName, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); + AddAsset(assets, packageId, packageVersion, sourcePath, fileName, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); if (relativePath.StartsWith("runtimes/", StringComparison.OrdinalIgnoreCase)) { - AddAsset(assets, packageId, sourcePath, relativePath, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); + AddAsset(assets, packageId, packageVersion, sourcePath, relativePath, isManagedAssembly: IsManagedAssembly(sourcePath), isNativeLibrary: false); } var xmlSourcePath = Path.ChangeExtension(sourcePath, ".xml"); if (File.Exists(xmlSourcePath)) { - AddAsset(assets, packageId, xmlSourcePath, Path.ChangeExtension(fileName, ".xml"), isManagedAssembly: false, isNativeLibrary: false); + AddAsset(assets, packageId, packageVersion, xmlSourcePath, Path.ChangeExtension(fileName, ".xml"), isManagedAssembly: false, isNativeLibrary: false); } } @@ -314,6 +318,7 @@ private static string GetFileName(string path) private static void AddRuntimeTargets( List assets, string packageId, + string packageVersion, IEnumerable runtimeTargets, string packagePath) { @@ -333,6 +338,7 @@ private static void AddRuntimeTargets( AddAsset( assets, packageId, + packageVersion, sourcePath, runtimeTarget.Path, isManagedAssembly: string.Equals(runtimeTarget.AssetType, "runtime", StringComparison.OrdinalIgnoreCase) && IsManagedAssembly(sourcePath), @@ -343,6 +349,7 @@ private static void AddRuntimeTargets( private static void AddResourceAssemblies( List assets, string packageId, + string packageVersion, IEnumerable resourceAssemblies, string packagePath) { @@ -371,6 +378,7 @@ private static void AddResourceAssemblies( AddAsset( assets, packageId, + packageVersion, sourcePath, Path.Combine(locale, Path.GetFileName(sourcePath)), isManagedAssembly: IsManagedAssembly(sourcePath), @@ -382,6 +390,7 @@ private static void AddResourceAssemblies( private static void AddNativeLibraries( List assets, string packageId, + string packageVersion, IEnumerable nativeLibraries, string packagePath) { @@ -398,14 +407,15 @@ private static void AddNativeLibraries( continue; } - AddAsset(assets, packageId, sourcePath, Path.GetFileName(sourcePath), isManagedAssembly: false, isNativeLibrary: true); - AddAsset(assets, packageId, sourcePath, nativeLib.Path, isManagedAssembly: false, isNativeLibrary: true); + AddAsset(assets, packageId, packageVersion, sourcePath, Path.GetFileName(sourcePath), isManagedAssembly: false, isNativeLibrary: true); + AddAsset(assets, packageId, packageVersion, sourcePath, nativeLib.Path, isManagedAssembly: false, isNativeLibrary: true); } } private static void AddAsset( List assets, string packageId, + string packageVersion, string sourcePath, string relativePath, bool isManagedAssembly, @@ -415,6 +425,7 @@ private static void AddAsset( assets.Add(new NuGetPackageAsset { PackageId = packageId, + PackageVersion = packageVersion, SourcePath = sourcePath, RelativePath = NormalizeRelativePath(relativePath), IsManagedAssembly = isManagedAssembly, diff --git a/src/Shared/IntegrationPackageProbeManifest.cs b/src/Shared/IntegrationPackageProbeManifest.cs index aadbac93e52..8d90d963cc2 100644 --- a/src/Shared/IntegrationPackageProbeManifest.cs +++ b/src/Shared/IntegrationPackageProbeManifest.cs @@ -51,7 +51,8 @@ public static IntegrationPackageProbeManifest Create( Name = NormalizeRequiredValue(assembly.Name, "managedAssemblies[].name"), Culture = NormalizeCulture(assembly.Culture), Path = NormalizeRequiredValue(assembly.Path, "managedAssemblies[].path"), - PackageId = NormalizeOptionalValue(assembly.PackageId) + PackageId = NormalizeOptionalValue(assembly.PackageId), + PackageVersion = NormalizeOptionalValue(assembly.PackageVersion) }; managedLookup.TryAdd( @@ -147,6 +148,10 @@ public static Task WriteAsync( { writer.WriteString("packageId", managedAssembly.PackageId); } + if (managedAssembly.PackageVersion is not null) + { + writer.WriteString("packageVersion", managedAssembly.PackageVersion); + } writer.WriteString("path", managedAssembly.Path); writer.WriteEndObject(); } @@ -396,7 +401,8 @@ private static IReadOnlyList ReadManagedAssem Name = NormalizeRequiredValue(ReadStringProperty(element, "name"), "managedAssemblies[].name"), Culture = NormalizeCulture(ReadStringProperty(element, "culture", required: false)), Path = NormalizeAndValidatePath(ReadStringProperty(element, "path"), "managedAssemblies[].path"), - PackageId = NormalizeOptionalValue(ReadStringProperty(element, "packageId", required: false)) + PackageId = NormalizeOptionalValue(ReadStringProperty(element, "packageId", required: false)), + PackageVersion = NormalizeOptionalValue(ReadStringProperty(element, "packageVersion", required: false)) }); } @@ -458,6 +464,8 @@ internal sealed class IntegrationPackageManagedAssembly public required string Path { get; init; } public string? PackageId { get; init; } + + public string? PackageVersion { get; init; } } /// diff --git a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs index 88f268492ab..3bd276eacaf 100644 --- a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs @@ -2117,6 +2117,7 @@ public async Task PrepareAsync_WithProjectReferences_WritesPackageProbeManifestA managedAssemblies, assembly => assembly.GetProperty("name").GetString() == "Aspire.Hosting.Redis" && assembly.GetProperty("packageId").GetString() == "Aspire.Hosting.Redis" && + assembly.GetProperty("packageVersion").GetString() == "13.2.0" && assembly.GetProperty("path").GetString() == Path.Combine(workingDirectory, "integration-restore", "closure-sources", "Aspire.Hosting.Redis.dll")); Assert.Equal(0, probeManifest.RootElement.GetProperty("nativeLibraries").GetArrayLength()); } diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs index ee341e8423c..bac95dfaac6 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AssemblyLoaderTests.cs @@ -195,6 +195,60 @@ public void GetAssemblies_AddsAssemblyNamesToProfilingSpan() Assert.Contains("Aspire.Hosting", loadedNames); } + [Fact] + public void TryGetPackageAssemblyNamesFromProbePaths_UsesManifestIdentityForCopiedClosureAssets() + { + using var manifestDirectory = new TemporaryDirectory(); + using var closureDirectory = new TemporaryDirectory(); + + var firstAssemblyPath = System.IO.Path.Combine(closureDirectory.Path, "Aspire.Hosting.Test.First.dll"); + var secondAssemblyPath = System.IO.Path.Combine(closureDirectory.Path, "Aspire.Hosting.Test.Second.dll"); + File.WriteAllText(firstAssemblyPath, string.Empty); + File.WriteAllText(secondAssemblyPath, string.Empty); + + var manifestPath = System.IO.Path.Combine(manifestDirectory.Path, IntegrationPackageProbeManifest.FileName); + WriteProbeManifest( + manifestPath, + managedAssemblies: + [ + new + { + Name = "Aspire.Hosting.Test.First", + PackageId = "Aspire.Hosting.Test.Package", + PackageVersion = "1.2.3", + Path = firstAssemblyPath + }, + new + { + Name = "Aspire.Hosting.Test.Second", + PackageId = "Aspire.Hosting.Test.Package", + PackageVersion = "1.2.3", + Path = secondAssemblyPath + } + ]); + + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["ASPIRE_INTEGRATION_PROBE_MANIFEST_PATH"] = manifestPath + }) + .Build(); + var loader = new AssemblyLoader( + configuration, + NullLogger.Instance, + CreateProfilingTelemetry()); + + Assert.True(loader.TryGetPackageAssemblyNamesFromProbePaths( + "aspire.hosting.test.package", + "1.2.3", + out var assemblyNames, + out var canonicalPackageId)); + Assert.Equal("Aspire.Hosting.Test.Package", canonicalPackageId); + Assert.Equal( + ["Aspire.Hosting.Test.First", "Aspire.Hosting.Test.Second"], + assemblyNames); + } + private static void WriteProbeManifest(string manifestPath, IEnumerable? managedAssemblies = null, IEnumerable? nativeLibraries = null) { File.WriteAllText( From 30f306dc633f87e263123f98a14e87be5e1bd0c9 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 14 Aug 2026 19:29:06 -0400 Subject: [PATCH 67/73] Ignore stale ATS capability registry entries Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d65b598f-72dd-4fca-bdc4-8debbbd7f821 --- .../AtsContextFilter.cs | 16 +++++++--- .../AtsContextFilterTests.cs | 31 +++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs index f1fc4722c68..307122795ba 100644 --- a/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs +++ b/src/Aspire.Hosting.RemoteHost/AtsContextFilter.cs @@ -541,9 +541,11 @@ private static bool IsSelectedAssembly(Assembly? assembly, HashSet assem private static HashSet GetKnownAssemblyNames(AtsContext context, HashSet assemblyNames) { var knownAssemblyNames = new HashSet(assemblyNames, StringComparer.OrdinalIgnoreCase); + var capabilityIds = new HashSet(StringComparer.Ordinal); foreach (var capability in context.Capabilities) { + capabilityIds.Add(capability.CapabilityId); AddAssemblyNameFromId(knownAssemblyNames, capability.CapabilityId); } @@ -569,14 +571,20 @@ private static HashSet GetKnownAssemblyNames(AtsContext context, HashSet AddAssemblyName(knownAssemblyNames, exportedValue.OwningAssemblyName); } - foreach (var method in context.Methods.Values) + foreach (var (capabilityId, method) in context.Methods) { - AddAssemblyName(knownAssemblyNames, method.DeclaringType?.Assembly); + if (capabilityIds.Contains(capabilityId)) + { + AddAssemblyName(knownAssemblyNames, method.DeclaringType?.Assembly); + } } - foreach (var property in context.Properties.Values) + foreach (var (capabilityId, property) in context.Properties) { - AddAssemblyName(knownAssemblyNames, property.DeclaringType?.Assembly); + if (capabilityIds.Contains(capabilityId)) + { + AddAssemblyName(knownAssemblyNames, property.DeclaringType?.Assembly); + } } return knownAssemblyNames; diff --git a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs index 17502dbb402..b421e41abf8 100644 --- a/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs +++ b/tests/Aspire.Hosting.RemoteHost.Tests/AtsContextFilterTests.cs @@ -71,6 +71,37 @@ public void TryResolveCanonicalAssemblyName_ReportsAnUnmatchedName() Assert.Empty(AtsContextFilter.FilterByExportingAssemblies(context, ["contoso.not.loaded"]).HandleTypes); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TryResolveCanonicalAssemblyName_IgnoresRegistryEntriesForRemovedCapabilities(bool useProperty) + { + var context = new AtsContext + { + Capabilities = [], + HandleTypes = [], + DtoTypes = [], + EnumTypes = [] + }; + + string assemblyName; + if (useProperty) + { + var property = typeof(AtsContext).GetProperty(nameof(AtsContext.Capabilities))!; + context.Properties["removed"] = property; + assemblyName = property.DeclaringType!.Assembly.GetName().Name!; + } + else + { + var method = typeof(AtsContextFilterTests).GetMethod(nameof(TryResolveCanonicalAssemblyName_ReportsAnUnmatchedName))!; + context.Methods["removed"] = method; + assemblyName = method.DeclaringType!.Assembly.GetName().Name!; + } + + Assert.False(AtsContextFilter.TryResolveCanonicalAssemblyName(context, assemblyName, out var resolvedName)); + Assert.Null(resolvedName); + } + /// Casing variants exercised by . public enum NameCasing { From 84ac5a090a5a488959acce299b8c295a539892a7 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Fri, 14 Aug 2026 19:29:06 -0400 Subject: [PATCH 68/73] Reject mismatched emulated core exports Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d65b598f-72dd-4fca-bdc4-8debbbd7f821 --- .../Commands/Sdk/SdkExportCommand.cs | 10 +++++ .../Commands/Sdk/SdkExportCommandTests.cs | 41 +++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 93f793b2b43..ea90149432a 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -6,6 +6,7 @@ using Aspire.Cli.Configuration; using Aspire.Cli.Interaction; using Aspire.Cli.Projects; +using Aspire.Cli.Utils; using Microsoft.Extensions.Logging; using Semver; using StreamJsonRpc; @@ -95,6 +96,15 @@ protected override async Task ExecuteAsync(ParseResult parseResul } } + var physicalSdkVersion = VersionHelper.GetDefaultSdkVersion(); + if (string.Equals(packageName, CorePackageName, StringComparison.Ordinal) && + !string.Equals(ExecutionContext.IdentitySdkVersion, physicalSdkVersion, StringComparison.OrdinalIgnoreCase)) + { + return CommandResult.Failure( + CliExitCodes.InvalidCommand, + $"This CLI reports SDK version {ExecutionContext.IdentitySdkVersion}, but its embedded {CorePackageName} surface is from {physicalSdkVersion}."); + } + var languageInfo = await FindLanguageAsync(language, cancellationToken); if (languageInfo is not null) { diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index c7197cc95d1..9361661e2b1 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -8,6 +8,7 @@ using Aspire.Cli.Projects; using Aspire.Cli.Tests.TestServices; using Aspire.Cli.Tests.Utils; +using Aspire.Cli.Utils; using Microsoft.AspNetCore.InternalTesting; using Microsoft.Extensions.DependencyInjection; using StreamJsonRpc; @@ -204,6 +205,31 @@ public async Task SdkExportRejectsCoreVersionDifferentFromTheCli() Assert.Null(rpcClient.LastExportRequest); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task SdkExportRejectsCoreWhenEmulatedVersionDiffersFromTheRunningBinary(bool specifyPackage) + { + var interactionService = new TestInteractionService(); + var physicalSdkVersion = VersionHelper.GetDefaultSdkVersion(); + var emulatedSdkVersion = physicalSdkVersion == "0.0.1" ? "0.0.2" : "0.0.1"; + using var provider = CreateProvider( + interactionService, + out var workspace, + out var rpcClient, + out _, + identityVersion: emulatedSdkVersion); + using var workspaceLease = workspace; + + var command = specifyPackage + ? $"sdk export --language typescript --package Aspire.Hosting@{emulatedSdkVersion}" + : "sdk export --language typescript"; + var exitCode = await InvokeAsync(provider, command); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Null(rpcClient.LastExportRequest); + } + [Fact] public async Task SdkExportUsesStructuredInvalidParametersForUnsupportedLanguage() { @@ -276,12 +302,13 @@ private ServiceProvider CreateProvider( TestInteractionService interactionService, out TemporaryWorkspace workspace, out StubExportRpcClient rpcClient, - out CapturingAppHostServerProject project) + out CapturingAppHostServerProject project, + string? identityVersion = null) { workspace = TemporaryWorkspace.CreateForCli(outputHelper); rpcClient = new StubExportRpcClient(); project = new CapturingAppHostServerProject(); - return CreateProvider(interactionService, out _, rpcClient, project, workspace); + return CreateProvider(interactionService, out _, rpcClient, project, workspace, identityVersion); } private ServiceProvider CreateProvider( @@ -289,12 +316,20 @@ private ServiceProvider CreateProvider( out TemporaryWorkspace workspace, IAppHostRpcClient rpcClient, IAppHostServerProject appHostServerProject, - TemporaryWorkspace? existingWorkspace = null) + TemporaryWorkspace? existingWorkspace = null, + string? identityVersion = null) { workspace = existingWorkspace ?? TemporaryWorkspace.CreateForCli(outputHelper); + var testWorkspace = workspace; var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper, options => { options.InteractionServiceFactory = _ => interactionService; + if (identityVersion is not null) + { + options.CliExecutionContextFactory = _ => testWorkspace.CreateExecutionContext( + identityVersion: identityVersion, + identityOverridden: true); + } }); services.AddSingleton(new TestAppHostServerProjectFactory From 5abdc5da6a4a76d6cf02b508cab7f79ffb67a301 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 24 Aug 2026 18:44:29 -0400 Subject: [PATCH 69/73] Address sdk export review findings Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5ddc8e81-7527-446e-97c0-d7db76bd6766 --- .../Commands/Sdk/SdkExportCommand.cs | 41 +- .../Projects/PrebuiltAppHostServer.cs | 4 + .../Resources/ErrorStrings.Designer.cs | 9 + src/Aspire.Cli/Resources/ErrorStrings.resx | 4 + .../Resources/xlf/ErrorStrings.cs.xlf | 5 + .../Resources/xlf/ErrorStrings.de.xlf | 5 + .../Resources/xlf/ErrorStrings.es.xlf | 5 + .../Resources/xlf/ErrorStrings.fr.xlf | 5 + .../Resources/xlf/ErrorStrings.it.xlf | 5 + .../Resources/xlf/ErrorStrings.ja.xlf | 5 + .../Resources/xlf/ErrorStrings.ko.xlf | 5 + .../Resources/xlf/ErrorStrings.pl.xlf | 5 + .../Resources/xlf/ErrorStrings.pt-BR.xlf | 5 + .../Resources/xlf/ErrorStrings.ru.xlf | 5 + .../Resources/xlf/ErrorStrings.tr.xlf | 5 + .../Resources/xlf/ErrorStrings.zh-Hans.xlf | 5 + .../Resources/xlf/ErrorStrings.zh-Hant.xlf | 5 + .../AtsTypeScriptCodeGenerator.cs | 124 +---- .../TypeScriptApiExportWriter.cs | 2 + .../TypeScriptApiModel.cs | 41 +- .../TypeScriptApiProjector.cs | 429 ++++++++++++++++-- .../Commands/Sdk/SdkExportCommandTests.cs | 31 ++ .../Projects/PrebuiltAppHostServerTests.cs | 26 ++ .../AtsTypeScriptCodeGeneratorTests.cs | 232 ++++++++++ 24 files changed, 839 insertions(+), 169 deletions(-) diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index ea90149432a..ecfe2188039 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -2,10 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; +using System.Globalization; using System.Text.Json; using Aspire.Cli.Configuration; using Aspire.Cli.Interaction; using Aspire.Cli.Projects; +using Aspire.Cli.Resources; using Aspire.Cli.Utils; using Microsoft.Extensions.Logging; using Semver; @@ -106,6 +108,16 @@ protected override async Task ExecuteAsync(ParseResult parseResul } var languageInfo = await FindLanguageAsync(language, cancellationToken); + if (languageInfo is not null && string.IsNullOrWhiteSpace(languageInfo.CodeGenerator)) + { + return CommandResult.Failure( + CliExitCodes.InvalidCommand, + string.Format( + CultureInfo.CurrentCulture, + ErrorStrings.SdkExportLanguageDoesNotSupportCodeGeneration, + languageInfo.DisplayName)); + } + if (languageInfo is not null) { var codeGenerationPackage = await _languageDiscovery.GetPackageForLanguageAsync( @@ -309,22 +321,41 @@ private static bool TryNormalizeFourPartVersion(string version, out string norma { normalizedVersion = string.Empty; - // NuGet accepts a four-component numeric version that SemVer does not: + // NuGet accepts a four-component numeric core that SemVer does not: // 1.2.3.4 + // 1.2.3.4-preview.1+build // Keep SemVersion as the primary parser so ordinary versions and prerelease labels retain - // their existing normalization, then narrowly fall back to System.Version for this shape. - var components = version.Split('.'); + // their existing normalization. For the fallback, parse the numeric core with System.Version + // and validate the remaining prerelease/build suffix independently as SemVer. + var suffixIndex = version.IndexOfAny(['-', '+']); + var numericCore = suffixIndex >= 0 ? version[..suffixIndex] : version; + var suffix = suffixIndex >= 0 ? version[suffixIndex..] : string.Empty; + var components = numericCore.Split('.'); if (components.Length != 4 || components.Any(static component => component.Length == 0 || component.Any(static character => !char.IsAsciiDigit(character))) || - !Version.TryParse(version, out var parsedVersion)) + !Version.TryParse(numericCore, out var parsedVersion)) { return false; } - normalizedVersion = parsedVersion.Revision == 0 + var normalizedCore = parsedVersion.Revision == 0 ? parsedVersion.ToString(3) : parsedVersion.ToString(4); + + if (suffix.Length == 0) + { + normalizedVersion = normalizedCore; + return true; + } + + const string SemVerCore = "0.0.0"; + if (!SemVersion.TryParse($"{SemVerCore}{suffix}", SemVersionStyles.Strict, out var parsedSuffix)) + { + return false; + } + + normalizedVersion = normalizedCore + parsedSuffix.ToString()[SemVerCore.Length..]; return true; } } diff --git a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs index 23a105ab581..298f1666b59 100644 --- a/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs +++ b/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs @@ -230,6 +230,10 @@ await IntegrationPackageProbeManifest.WriteAsync( ChannelName: requestedChannel, NeedsCodeGeneration: true); } + catch (OperationCanceledException) + { + throw; + } catch (AppHostServerPrepareFailedException ex) { _logger.LogError(ex, "Failed to prepare prebuilt AppHost server"); diff --git a/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs b/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs index 24f17250b49..344f3672fa7 100644 --- a/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs +++ b/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs @@ -506,5 +506,14 @@ public static string IntegrationBuildPackageDowngradeFailed { return ResourceManager.GetString("IntegrationBuildPackageDowngradeFailed", resourceCulture); } } + + /// + /// Looks up a localized string similar to SDK API export is not supported for {0} because it does not use a code generator.. + /// + public static string SdkExportLanguageDoesNotSupportCodeGeneration { + get { + return ResourceManager.GetString("SdkExportLanguageDoesNotSupportCodeGeneration", resourceCulture); + } + } } } diff --git a/src/Aspire.Cli/Resources/ErrorStrings.resx b/src/Aspire.Cli/Resources/ErrorStrings.resx index 95334f66125..8a52eee45a2 100644 --- a/src/Aspire.Cli/Resources/ErrorStrings.resx +++ b/src/Aspire.Cli/Resources/ErrorStrings.resx @@ -298,4 +298,8 @@ The integration project could not be built because a referenced project requires a newer version of Aspire.Hosting than this Aspire CLI ({0}) provides. The AppHost server is the CLI itself, so project references in aspire.config.json must target the same version the CLI ships. Either use an Aspire CLI that matches the referenced projects, or reference published packages instead of local projects. {0} is the version of the running Aspire CLI, for example "13.5.0". + + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf index ba2329333ab..cc134fdf6d8 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf @@ -267,6 +267,11 @@ Projekt neobsahuje hostitele aplikací Aspire. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. Funkce AppHost pro jednosouborové scénáře není povolená. Chcete-li používat .cs soubory AppHost, povolte tuto funkci v konfiguraci diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf index 6d520ce31e4..c5a2f660488 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf @@ -267,6 +267,11 @@ Das Projekt enthält keinen Aspire-AppHost. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. Das AppHost-Feature für einzelne Dateien ist nicht aktiviert. Um .cs-AppHost-Dateien zu verwenden, aktivieren Sie das Feature über die Konfiguration. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf index 885f5acc240..4c028958ab3 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf @@ -267,6 +267,11 @@ El proyecto no contiene ningún apphost de Aspire. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. La característica AppHost de un solo archivo no está habilitada. Para usar archivos AppHost .cs, habilite la función mediante la configuración. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf index b4e0cc9568a..754375122b9 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf @@ -267,6 +267,11 @@ Le projet ne contient pas d’Aspire AppHost. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. La fonctionnalité d’hôte d’application à fichier unique n’est pas activée. Pour utiliser les fichiers AppHost .cs, activez la fonctionnalité via la configuration. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf index b8928b75884..885cbf2922b 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf @@ -267,6 +267,11 @@ Il progetto non contiene un AppHost Aspire. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. La funzionalità AppHost a file singolo non è abilitata. Per usare i file AppHost .cs, abilitare la funzionalità tramite la configurazione. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf index 86ad16f6593..7ad801d51ff 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf @@ -267,6 +267,11 @@ プロジェクトに Aspire AppHost が含まれていません。 + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. 単一ファイル AppHost 機能が有効になっていません。.cs AppHost ファイルを使用するには、構成を使用して機能を有効にします。 diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf index d340c4db062..83b17d1fca9 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf @@ -267,6 +267,11 @@ 프로젝트에 Aspire AppHost가 포함되어 있지 않습니다. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. 단일 파일 AppHost 기능을 사용할 수 없습니다. .cs AppHost 파일을 사용하려면 설정을 사용하여 기능을 활성화해야 합니다. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf index 40e17a49c2f..5a786c4fea0 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf @@ -267,6 +267,11 @@ Projekt nie zawiera hosta AppHost platformy Aspire. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. Funkcja hosta AppHost z jednym plikiem nie jest włączona. Aby użyć plików .cs hosta AppHost, włącz tę funkcję przy użyciu konfiguracji. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf index 0338167c801..3545168624d 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf @@ -267,6 +267,11 @@ O projeto não contém um AppHost do Aspire. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. O recurso AppHost de arquivo único não está habilitado. Para usar arquivos AppHost .cs, habilite o recurso usando a configuração. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf index a40c7e83b1e..a3c28d801bf 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf @@ -267,6 +267,11 @@ Проект не содержит хост приложений Aspire. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. Функция одиночного файла AppHost не включена. Чтобы использовать CS-файлы AppHost, включите эту функцию с помощью конфигурации. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf index 9e8859bf815..bc4381e7491 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf @@ -267,6 +267,11 @@ Proje bir Aspire AppHost içermiyor. + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. Tek dosya Uygulama Ana İşlemi özelliği etkinleştirilmemiştir. .cs AppHost dosyalarını kullanmak için, yapılandırmaları kullanarak özelliği etkinleştirin. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf index 7ddd0388dbf..9a7a77a09ef 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf @@ -267,6 +267,11 @@ 该项目不包含 Aspire 应用主机。 + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. 未启用单文件应用主机功能。要使用 .cs AppHost 文件,请通过配置启用该功能。 diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf index 8718b39e291..41bd661bca6 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf @@ -267,6 +267,11 @@ 該專案不包含 Aspire AppHost。 + + SDK API export is not supported for {0} because it does not use a code generator. + SDK API export is not supported for {0} because it does not use a code generator. + {0} is the AppHost language display name, for example "C# (.NET)". + Single file AppHost feature is not enabled. To use .cs AppHost files, enable the feature using configuration. 未啟用單一檔案 AppHost 功能。若要使用 .cs AppHost 檔案,請使用設定啟用此功能。 diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs index ad37508106a..a26bd087681 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs @@ -3,8 +3,6 @@ using System.Globalization; using System.Text; -using System.Text.Json.Nodes; -using Aspire.Shared.Json; using Aspire.TypeSystem; namespace Aspire.Hosting.CodeGeneration.TypeScript; @@ -22,13 +20,6 @@ internal sealed class BuilderModel public AtsTypeRef? TargetType { get; init; } } -internal sealed class ExportedValueTreeNode -{ - public Dictionary Children { get; } = new(StringComparer.Ordinal); - - public AtsExportedValueInfo? Value { get; set; } -} - /// /// Generates a TypeScript SDK using the ATS (Aspire Type System) capability-based API. /// Produces typed builder classes with fluent methods that use invokeCapability(). @@ -530,7 +521,7 @@ import type { GenerateDtoInterfaces(dtoTypes); // Generate exported immutable values - GenerateExportedValues(exportedValues, dtoTypes.ToDictionary(dto => dto.TypeId, StringComparer.Ordinal)); + GenerateExportedValues(exportedValues); // Generate collected options interfaces GenerateOptionsInterfaces(); @@ -693,132 +684,27 @@ private void GenerateDtoInterfaces(IReadOnlyList dtoTypes) } } - private void GenerateExportedValues( - IReadOnlyList exportedValues, - IReadOnlyDictionary dtoTypesById) + private void GenerateExportedValues(IReadOnlyList exportedValues) { if (exportedValues.Count == 0) { return; } - var root = BuildExportedValueTree(exportedValues); + var namespaces = _projector.ProjectExportedValues(exportedValues); WriteLine("// ============================================================================"); WriteLine("// Exported Values"); WriteLine("// ============================================================================"); WriteLine(); - foreach (var (name, node) in root.Children.OrderBy(pair => pair.Key, StringComparer.Ordinal)) - { - WriteLine($"export namespace {name} {{"); - WriteTypeScriptExportedValueChildren(node, dtoTypesById, indentLevel: 1); - WriteLine("}"); - WriteLine(); - } - } - - private void WriteTypeScriptExportedValueChildren( - ExportedValueTreeNode node, - IReadOnlyDictionary dtoTypesById, - int indentLevel) - { - var indent = new string(' ', indentLevel * 4); - - foreach (var (name, child) in node.Children.OrderBy(pair => pair.Key, StringComparer.Ordinal)) + foreach (var exportedNamespace in namespaces) { - if (child.Value is { } valueInfo) - { - WriteDocumentationComment(indent, valueInfo.Documentation, valueInfo.Description); - - var literal = RenderTypeScriptExportedValue(valueInfo.Value, valueInfo.Type, dtoTypesById); - var exportedType = _projector.MapTypeRefToTypeScript(valueInfo.Type); - var needsCast = valueInfo.Type.Category is not AtsTypeCategory.Primitive; - var expression = needsCast ? $"{literal} as {exportedType}" : literal; - WriteLine($"{indent}export const {name} = {expression};"); - } - else - { - WriteLine($"{indent}export namespace {name} {{"); - WriteTypeScriptExportedValueChildren(child, dtoTypesById, indentLevel + 1); - WriteLine($"{indent}}}"); - } - + WriteLine(exportedNamespace.Content); WriteLine(); } } - private string RenderTypeScriptExportedValue( - JsonNode? value, - AtsTypeRef typeRef, - IReadOnlyDictionary dtoTypesById) - { - if (value is null) - { - return "null"; - } - - return typeRef.Category switch - { - AtsTypeCategory.Dto when value is JsonObject obj && dtoTypesById.TryGetValue(typeRef.TypeId, out var dtoInfo) - => RenderTypeScriptDtoValue(obj, dtoInfo, dtoTypesById), - AtsTypeCategory.Array or AtsTypeCategory.List when value is JsonArray arr - => $"[{string.Join(", ", arr.Select(item => RenderTypeScriptExportedValue(item, typeRef.ElementType!, dtoTypesById)))}]", - AtsTypeCategory.Dict when value is JsonObject obj - => "{ " + string.Join(", ", obj.Select(pair => $"{RenderTypeScriptPropertyKey(pair.Key)}: {RenderTypeScriptExportedValue(pair.Value, typeRef.ValueType!, dtoTypesById)}")) + " }", - _ => value.ToRelaxedJsonString() - }; - } - - private string RenderTypeScriptDtoValue( - JsonObject value, - AtsDtoTypeInfo dtoInfo, - IReadOnlyDictionary dtoTypesById) - { - var members = new List(); - - foreach (var property in dtoInfo.Properties) - { - if (!value.TryGetPropertyValue(property.Name, out var propertyValue)) - { - continue; - } - - members.Add($"{TypeScriptApiProjector.ToCamelCase(property.Name)}: {RenderTypeScriptExportedValue(propertyValue, property.Type, dtoTypesById)}"); - } - - return "{ " + string.Join(", ", members) + " }"; - } - - private static string RenderTypeScriptPropertyKey(string key) - { - return AtsJsonCodeWriter.ToRelaxedJsonString(key); - } - - private static ExportedValueTreeNode BuildExportedValueTree(IReadOnlyList exportedValues) - { - var root = new ExportedValueTreeNode(); - - foreach (var exportedValue in exportedValues) - { - var current = root; - foreach (var segment in exportedValue.PathSegments) - { - if (!current.Children.TryGetValue(segment, out var child)) - { - child = new ExportedValueTreeNode(); - current.Children[segment] = child; - } - - current = child; - } - - current.Value = exportedValue; - } - - return root; - } - /// /// Generates all collected options interfaces. /// diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs index 73b904ae962..9143e3ca08e 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiExportWriter.cs @@ -162,6 +162,8 @@ private static JsonObject WriteMember(TypeScriptApiMember member) TypeScriptApiItemKind.Enum => "enum", TypeScriptApiItemKind.Dto => "dto", TypeScriptApiItemKind.Options => "options", + TypeScriptApiItemKind.Namespace => "namespace", + TypeScriptApiItemKind.Constant => "constant", TypeScriptApiItemKind.Augmentation => "augmentation", TypeScriptApiItemKind.Method => "method", TypeScriptApiItemKind.Property => "property", diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs index b5823087517..f36cc7a9368 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiModel.cs @@ -22,6 +22,12 @@ internal enum TypeScriptApiItemKind /// A generated options bag interface for a method's optional parameters. Options, + /// A namespace containing immutable exported values. + Namespace, + + /// An immutable exported value. + Constant, + /// /// The members this package contributes to an interface another package owns. The owning package /// publishes the type itself, so this is deliberately not a second page for that type. @@ -169,28 +175,43 @@ internal sealed record TypeScriptApiModule public required IReadOnlyList Items { get; init; } } +/// +/// A fully rendered exported-value namespace shared by source generation and canonical projection. +/// +internal sealed record TypeScriptExportedValueNamespace +{ + /// Gets the namespace name. + public required string Name { get; init; } + + /// Gets the complete TypeScript namespace declaration. + public required string Content { get; init; } + + /// Gets the namespace and constant members exposed for canonical documentation. + public required IReadOnlyList Members { get; init; } +} + /// /// A generator-owned TypeScript declaration fragment. /// /// -/// Concatenating the fragments of one complete manifest, ordered and deduplicated by -/// , must type-check on its own. Fragments contributed by the referenced-type -/// closure carry the owning assembly of the referenced type so consumers can avoid creating -/// duplicate documentation pages for another package's symbols. +/// Declaration IDs are scoped to the containing package export. The canonical identity of a +/// declaration is the tuple (package.name, package.version, declaration.id); declarations +/// from separate package exports cannot be flattened into one global declaration set because +/// package-local TypeScript names may intentionally overlap. The complete declaration list in one +/// export must type-check on its own. /// internal sealed record TypeScriptApiDeclaration { private readonly string _content = string.Empty; - /// Gets the stable, generator-owned identifier used for ordering and deduplication. + /// Gets the stable, generator-owned identifier within the containing package export. public required string Id { get; init; } /// Gets the TypeScript declaration text. /// /// Line endings are normalized to \n. Some fragments come from raw string literals, which - /// carry whatever line endings the source file was checked out with, and consumers deduplicate - /// fragments by comparing content across packages — so a CLI built on Windows would otherwise - /// disagree with one built on Linux about the very same declaration. + /// carry whatever line endings the source file was checked out with, so the same package export + /// would otherwise differ between a CLI built on Windows and one built on Linux. /// public required string Content { @@ -222,7 +243,9 @@ internal sealed record TypeScriptApiModel /// Gets the package-owned documentation modules. public required IReadOnlyList Modules { get; init; } - /// Gets the declaration fragments needed to type-check the exported surface. + /// + /// Gets the package-scoped declaration fragments needed to type-check the exported surface. + /// public required IReadOnlyList Declarations { get; init; } } diff --git a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs index a7f50301ecc..f84bb5aa8fb 100644 --- a/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs +++ b/src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptApiProjector.cs @@ -3,8 +3,10 @@ using System.Reflection; using System.Text; +using System.Text.Json.Nodes; using System.Text.RegularExpressions; using Aspire.Shared.CodeGeneration; +using Aspire.Shared.Json; using Aspire.TypeSystem; namespace Aspire.Hosting.CodeGeneration.TypeScript; @@ -34,10 +36,9 @@ internal sealed partial class TypeScriptApiProjector /// /// Base library symbols that generated declarations reference but that the SDK ships by hand in - /// base.mts/transport.mts rather than generating per package. They are emitted as a - /// single declaration fragment with a well-known ID so that concatenating the fragments of a - /// complete manifest type-checks without site-authored shims, and so that deduplication by ID - /// collapses the copies contributed by every package in the manifest to exactly one. + /// base.mts/transport.mts rather than generating per package. Each package export + /// includes these symbols under a well-known package-local declaration ID so its declarations + /// type-check without site-authored shims. /// private const string RuntimeDeclarationId = "aspire:runtime:base"; @@ -268,15 +269,17 @@ private TypeScriptResolvedModel Resolve(AtsContext context) // Pre-scan all capabilities to collect options interfaces. // This must happen AFTER wrapper class names are populated so types resolve correctly. - foreach (var builder in builders) + // Options names are public TypeScript API. Allocate collision suffixes after sorting by the + // stable capability identity so a combined context produces byte-identical output regardless + // of the order in which package capabilities were discovered. + foreach (var cap in builders + .SelectMany(builder => builder.Capabilities) + .OrderBy(capability => capability.CapabilityId, StringComparer.Ordinal)) { - foreach (var cap in builder.Capabilities) + var (_, optionalParams) = SeparateParameters(cap.Parameters); + if (optionalParams.Count > 0 && !TryGetDirectOptionsParameter(optionalParams, out _)) { - var (_, optionalParams) = SeparateParameters(cap.Parameters); - if (optionalParams.Count > 0 && !TryGetDirectOptionsParameter(optionalParams, out _)) - { - RegisterOptionsInterface(cap.CapabilityId, cap.MethodName, optionalParams, GetCapabilityOwningAssemblyName(context, cap)); - } + RegisterOptionsInterface(cap.CapabilityId, cap.MethodName, optionalParams, GetCapabilityOwningAssemblyName(context, cap)); } } @@ -430,9 +433,9 @@ private string ResolveTypeClassReturnType(BuilderModel builder, AtsCapabilityInf /// Builds the canonical API export model for one package from the already-resolved projection. /// /// - /// Declaration fragment IDs are keyed by the assembly that owns the symbol rather than by the - /// exporting package, so a manifest that concatenates several packages collapses shared - /// referenced types to a single declaration instead of one copy per package. + /// Declaration fragment IDs are local to . Their canonical identity is + /// (package.name, package.version, declaration.id); consumers must not flatten declarations + /// from separate package exports because their package-local TypeScript names can overlap. /// /// The exact package identity the export is produced for. /// @@ -522,11 +525,36 @@ internal TypeScriptApiModel BuildApiModel( } } + var exportedValues = _resolved.Context.ExportedValues + .Where(value => owned.Contains(value.OwningAssemblyName)) + .ToList(); + foreach (var exportedNamespace in ProjectExportedValues(exportedValues)) + { + cancellationToken.ThrowIfCancellationRequested(); + var item = new TypeScriptApiItem + { + Id = $"namespace:{exportedNamespace.Name}", + TypeId = $"namespace:{exportedNamespace.Name}", + Kind = TypeScriptApiItemKind.Namespace, + Name = exportedNamespace.Name, + Declaration = $"export namespace {exportedNamespace.Name}", + OwningAssemblyName = package.Name, + Members = exportedNamespace.Members + }; + var declaration = new TypeScriptApiDeclaration + { + Id = $"{package.Name}:namespace:{exportedNamespace.Name}", + Content = exportedNamespace.Content, + OwningAssemblyName = package.Name + }; + + items.Add(item); + declarations[declaration.Id] = declaration; + } + // Options interfaces belong to the assembly whose capability produced them, which is what - // both their fragment ID and their documented-item gate key off. Attributing them to the - // requesting package instead would give the same interface a different ID in every export - // that reaches it, so concatenated fragments would redeclare it rather than dedupe, and a - // package would document options interfaces belonging to its dependencies. + // both their fragment ID and their documented-item gate key off. Otherwise, a package could + // document options interfaces belonging to its dependencies. foreach (var (interfaceName, optionalParams) in _optionsInterfacesToGenerate.OrderBy(kvp => kvp.Key, StringComparer.Ordinal)) { cancellationToken.ThrowIfCancellationRequested(); @@ -543,9 +571,9 @@ internal TypeScriptApiModel BuildApiModel( // Types reached through the referenced-type closure are named by generated unions and // parameters but have no capabilities of their own in this context, so nothing above - // declared them. Emit an opaque interface for each so the concatenated declarations - // type-check standalone. They deliberately produce no documented item: the package that - // owns them publishes their real surface. + // declared them. Emit an opaque interface for each so this package's declarations type-check + // standalone. They deliberately produce no documented item: the package that owns them + // publishes their real surface. // Deduplicate by declared name rather than by type ID: several ATS type IDs can resolve to // the same generated interface name, and emitting a stub for one of them would redeclare a // type another fragment already declares in full. @@ -640,6 +668,282 @@ internal TypeScriptApiModel BuildApiModel( }; } + /// + /// Projects exported values into namespace declarations shared by source generation and API export. + /// + /// The values to project. + /// The rendered top-level namespaces and their canonical members. + internal IReadOnlyList ProjectExportedValues( + IReadOnlyList exportedValues) + { + var root = BuildExportedValueTree(exportedValues); + var namespaces = new List(); + + foreach (var (name, node) in root.Children.OrderBy(pair => pair.Key, StringComparer.Ordinal)) + { + var content = new StringBuilder(); + var members = new List(); + content.Append("export namespace ").Append(name).Append(" {\n"); + AppendExportedValueChildren(content, node, [name], members, indentLevel: 1); + content.Append('}'); + namespaces.Add(new TypeScriptExportedValueNamespace + { + Name = name, + Content = content.ToString(), + Members = members + }); + } + + return namespaces; + } + + private void AppendExportedValueChildren( + StringBuilder content, + ExportedValueTreeNode node, + IReadOnlyList parentPath, + List members, + int indentLevel) + { + var indent = new string(' ', indentLevel * 4); + + foreach (var (name, child) in node.Children.OrderBy(pair => pair.Key, StringComparer.Ordinal)) + { + var path = parentPath.Append(name).ToArray(); + if (child.Value is { } valueInfo) + { + foreach (var documentationLine in RenderDocumentationComment( + indent, + valueInfo.Documentation, + valueInfo.Description)) + { + content.Append(documentationLine).Append('\n'); + } + + var declaration = $"export const {name} = {RenderTypeScriptExportedValueExpression(valueInfo)}"; + content.Append(indent).Append(declaration).Append(";\n"); + members.Add(new TypeScriptApiMember + { + Id = $"constant:{string.Join(".", path)}", + Kind = TypeScriptApiItemKind.Constant, + Name = name, + Declaration = declaration, + Summary = valueInfo.Documentation?.Summary ?? valueInfo.Description, + Remarks = valueInfo.Documentation?.Remarks, + OwningAssemblyName = valueInfo.OwningAssemblyName + }); + } + else + { + var declaration = $"export namespace {name}"; + content.Append(indent).Append(declaration).Append(" {\n"); + members.Add(new TypeScriptApiMember + { + Id = $"namespace:{string.Join(".", path)}", + Kind = TypeScriptApiItemKind.Namespace, + Name = name, + Declaration = declaration + }); + AppendExportedValueChildren(content, child, path, members, indentLevel + 1); + content.Append(indent).Append("}\n"); + } + + content.Append('\n'); + } + } + + private string RenderTypeScriptExportedValueExpression(AtsExportedValueInfo exportedValue) + { + var literal = RenderTypeScriptExportedValue(exportedValue.Value, exportedValue.Type); + var exportedType = MapTypeRefToTypeScript(exportedValue.Type); + + return exportedValue.Type.Category is AtsTypeCategory.Primitive + ? literal + : $"{literal} as {exportedType}"; + } + + private string RenderTypeScriptExportedValue(JsonNode? value, AtsTypeRef typeRef) + { + if (value is null) + { + return "null"; + } + + return typeRef.Category switch + { + AtsTypeCategory.Dto when value is JsonObject obj && _dtoTypesById.TryGetValue(typeRef.TypeId, out var dtoInfo) + => RenderTypeScriptDtoValue(obj, dtoInfo), + AtsTypeCategory.Array or AtsTypeCategory.List when value is JsonArray arr + => $"[{string.Join(", ", arr.Select(item => RenderTypeScriptExportedValue(item, typeRef.ElementType!)))}]", + AtsTypeCategory.Dict when value is JsonObject obj + => "{ " + string.Join(", ", obj.Select(pair => $"{AtsJsonCodeWriter.ToRelaxedJsonString(pair.Key)}: {RenderTypeScriptExportedValue(pair.Value, typeRef.ValueType!)}")) + " }", + _ => value.ToRelaxedJsonString() + }; + } + + private string RenderTypeScriptDtoValue(JsonObject value, AtsDtoTypeInfo dtoInfo) + { + var members = new List(); + + foreach (var property in dtoInfo.Properties) + { + if (value.TryGetPropertyValue(property.Name, out var propertyValue)) + { + members.Add($"{ToCamelCase(property.Name)}: {RenderTypeScriptExportedValue(propertyValue, property.Type)}"); + } + } + + return "{ " + string.Join(", ", members) + " }"; + } + + private static IReadOnlyList RenderDocumentationComment( + string indent, + AtsDocumentationInfo? documentation, + string? fallbackSummary) + { + var lines = new List(); + AddDocumentationLines(lines, documentation?.Summary ?? fallbackSummary); + AddDocumentationLines(lines, documentation?.Remarks, addBlankLineBefore: lines.Count > 0); + AddTaggedDocumentationLines(lines, "@returns", documentation?.Returns); + + if (lines.Count == 0) + { + return []; + } + + if (lines.Count == 1 && !lines[0].StartsWith('@')) + { + return [$"{indent}/** {lines[0]} */"]; + } + + var comment = new List { $"{indent}/**" }; + comment.AddRange(lines.Select(line => line.Length == 0 ? $"{indent} *" : $"{indent} * {line}")); + comment.Add($"{indent} */"); + return comment; + } + + private static void AddTaggedDocumentationLines(List lines, string tag, string? text) + { + var tagLines = SplitDocumentationLines(text); + if (tagLines.Count == 0) + { + return; + } + + lines.Add($"{tag} {tagLines[0]}"); + lines.AddRange(tagLines.Skip(1)); + } + + private static void AddDocumentationLines(List lines, string? text, bool addBlankLineBefore = false) + { + var textLines = SplitDocumentationLines(text); + if (textLines.Count == 0) + { + return; + } + + if (addBlankLineBefore) + { + lines.Add(string.Empty); + } + + lines.AddRange(textLines); + } + + private static List SplitDocumentationLines(string? text) + { + if (string.IsNullOrWhiteSpace(text)) + { + return []; + } + + return text + .Replace("\r\n", "\n", StringComparison.Ordinal) + .Replace('\r', '\n') + .Split('\n', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Select(EscapeJSDocText) + .ToList(); + } + + private static string EscapeJSDocText(string text) => + ConvertAtsReferencesToJsDocLinks(text).Replace("*/", "* /", StringComparison.Ordinal); + + private static string ConvertAtsReferencesToJsDocLinks(string text) + { + const string markerStart = "{@ats-ref "; + var startIndex = text.IndexOf(markerStart, StringComparison.Ordinal); + if (startIndex < 0) + { + return text; + } + + var builder = new StringBuilder(text.Length); + var currentIndex = 0; + + while (startIndex >= 0) + { + builder.Append(text, currentIndex, startIndex - currentIndex); + var markerBodyStartIndex = startIndex + markerStart.Length; + var markerEndIndex = text.IndexOf('}', markerBodyStartIndex); + if (markerEndIndex < 0) + { + builder.Append(text, startIndex, text.Length - startIndex); + return builder.ToString(); + } + + var markerBody = text[markerBodyStartIndex..markerEndIndex]; + var labelSeparatorIndex = markerBody.IndexOf('|', StringComparison.Ordinal); + var reference = labelSeparatorIndex < 0 ? markerBody : markerBody[..labelSeparatorIndex]; + var label = labelSeparatorIndex < 0 ? null : markerBody[(labelSeparatorIndex + 1)..]; + var targetSeparatorIndex = reference.IndexOf(':', StringComparison.Ordinal); + + if (targetSeparatorIndex < 0 || targetSeparatorIndex == reference.Length - 1) + { + builder.Append(text, startIndex, markerEndIndex - startIndex + 1); + } + else + { + var target = reference[(targetSeparatorIndex + 1)..]; + builder.Append("{@link ").Append(target); + if (!string.IsNullOrWhiteSpace(label)) + { + builder.Append('|').Append(label); + } + + builder.Append('}'); + } + + currentIndex = markerEndIndex + 1; + startIndex = text.IndexOf(markerStart, currentIndex, StringComparison.Ordinal); + } + + builder.Append(text, currentIndex, text.Length - currentIndex); + return builder.ToString(); + } + + private static ExportedValueTreeNode BuildExportedValueTree(IReadOnlyList exportedValues) + { + var root = new ExportedValueTreeNode(); + + foreach (var exportedValue in exportedValues) + { + var current = root; + foreach (var segment in exportedValue.PathSegments) + { + if (!current.Children.TryGetValue(segment, out var child)) + { + child = new ExportedValueTreeNode(); + current.Children[segment] = child; + } + + current = child; + } + + current.Value = exportedValue; + } + + return root; + } + private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() { var assembly = typeof(TypeScriptApiProjector).Assembly; @@ -657,8 +961,8 @@ private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() /// /// A package can extend a type another package owns. When that happens the type itself is not /// documented here — the owning package publishes it — but the members this package contributes - /// still are, and they are emitted as a separate interface augmentation fragment so TypeScript - /// declaration merging reassembles the full type when a manifest concatenates every package. + /// still are. They are emitted as a separate interface augmentation fragment so TypeScript + /// declaration merging reassembles the referenced stub and this package's contributed surface. /// private (TypeScriptApiItem? Item, List Declarations) ProjectBuilder( TypeScriptApiPackageIdentity package, @@ -674,12 +978,18 @@ private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() .Where(capability => ownedAssemblyNames.Contains(GetCapabilityOwningAssemblyName(capability))) .ToList(); + var promiseMembers = new List(); var getters = exportedCapabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertyGetter).ToList(); var setters = exportedCapabilities.Where(c => c.CapabilityKind == AtsCapabilityKind.PropertySetter).ToList(); foreach (var property in GroupPropertiesByName(getters, setters)) { - members.Add(ProjectProperty(interfaceName, property.PropertyName, property.Getter, property.Setter)); + var member = ProjectProperty(interfaceName, property.PropertyName, property.Getter, property.Setter); + members.Add(member); + if (IsGetterOnlyProperty(property.Getter, property.Setter)) + { + promiseMembers.Add(member); + } } // Type classes only surface instance and static methods; resource builders surface every @@ -694,7 +1004,9 @@ private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() foreach (var capability in methods) { - members.Add(ProjectMethod(interfaceName, builderModel, capability)); + var member = ProjectMethod(interfaceName, builderModel, capability); + members.Add(member); + promiseMembers.Add(member); } var documentation = _handleDocumentationById.GetValueOrDefault(builderModel.TypeId); @@ -722,7 +1034,7 @@ private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() declarations.Add(new TypeScriptApiDeclaration { Id = $"{typeOwner}:interface:{promiseInterfaceName}", - Content = BuildInterfaceBody(promiseInterfaceName, [$"PromiseLike<{interfaceName}>"], members, includeToJson: false), + Content = BuildInterfaceBody(promiseInterfaceName, [$"PromiseLike<{interfaceName}>"], promiseMembers, includeToJson: false), OwningAssemblyName = typeOwner }); } @@ -730,8 +1042,7 @@ private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() return (BuildInterfaceItem(builderModel, $"interface:{interfaceName}", interfaceName, extends, typeOwner, documentation, members, TypeScriptApiItemKind.Interface), declarations); } - // The referenced type gets an opaque stub keyed by its real owner so every package that - // references it contributes the identical fragment and deduplication collapses them. + // The referenced type gets one opaque stub keyed by its real owner within this package export. declarations.Add(new TypeScriptApiDeclaration { Id = $"{typeOwner}:opaque:{interfaceName}", @@ -766,16 +1077,14 @@ private static TypeScriptApiGeneratorIdentity CreateGeneratorIdentity() declarations.Add(new TypeScriptApiDeclaration { Id = $"{package.Name}:augment:{promiseInterfaceName}", - Content = BuildInterfaceBody(promiseInterfaceName, [], members, includeToJson: false), + Content = BuildInterfaceBody(promiseInterfaceName, [], promiseMembers, includeToJson: false), OwningAssemblyName = package.Name }); } - // The item carries the real owner and a distinct ID: the owning package already publishes a - // page for this type, and reusing "interface:{name}" here would collide with it across a - // manifest and claim the type belongs to whichever package happened to extend it. The - // contributing package is part of the ID because every integration that extends - // DistributedApplicationBuilder produces an augmentation for the same interface name. + // The item carries the real owner and a distinct ID because it describes only this package's + // contribution, not a second copy of the referenced type. Include the contributing package + // because an aggregate export can contain several augmentations for the same interface name. return (BuildInterfaceItem(builderModel, $"augmentation:{package.Name}:{interfaceName}", interfaceName, extends, typeOwner, documentation, members, TypeScriptApiItemKind.Augmentation), declarations); } @@ -1881,13 +2190,20 @@ private void AssignOptionsInterface( { if (_optionsInterfacesToGenerate.TryGetValue(interfaceName, out var declaredParams)) { - var declaredNames = new HashSet(declaredParams.Select(p => p.Name), StringComparer.Ordinal); foreach (var param in optionalParams) { - if (declaredNames.Add(param.Name)) + var declaredIndex = declaredParams.FindIndex( + declared => string.Equals(declared.Name, param.Name, StringComparison.Ordinal)); + if (declaredIndex < 0) { declaredParams.Add(param); } + else if (declaredParams[declaredIndex].Documentation is null && param.Documentation is not null) + { + // Compatible overloads can contribute the same option with different metadata. + // Keep the documented form regardless of which capability has the lower stable ID. + declaredParams[declaredIndex] = param; + } } } else @@ -2341,6 +2657,7 @@ internal static List CreateBuilderModels(IReadOnlyList c.CapabilityId) .Select(g => g.First()) .ToList(); + SortOptionsInterfaceCollisionsByCapabilityIdentity(uniqueCapabilities); var builder = new BuilderModel { @@ -2374,6 +2691,7 @@ internal static List CreateBuilderModels(IReadOnlyList c.CapabilityId) .Select(g => g.First()) .ToList(); + SortOptionsInterfaceCollisionsByCapabilityIdentity(uniqueCapabilities); var builder = new BuilderModel { @@ -2458,6 +2776,38 @@ internal static List CreateBuilderModels(IReadOnlyList capabilities) + { + // Reorder only colliding option-interface slots. Sorting every capability would rewrite + // long-established source order for methods unrelated to the collision. + var collisionGroups = capabilities + .Select((capability, index) => (Capability: capability, Index: index)) + .Where(entry => + { + var (_, optionalParameters) = SeparateParameters(entry.Capability.Parameters); + return optionalParameters.Count > 0 && + !TryGetDirectOptionsParameter(optionalParameters, out _); + }) + .GroupBy( + entry => GetOptionsInterfaceName(entry.Capability.MethodName), + StringComparer.Ordinal) + .Where(group => group.Count() > 1); + + foreach (var group in collisionGroups) + { + var indexes = group.Select(entry => entry.Index).Order().ToList(); + var orderedCapabilities = group + .Select(entry => entry.Capability) + .OrderBy(capability => capability.CapabilityId, StringComparer.Ordinal) + .ToList(); + + for (var i = 0; i < indexes.Count; i++) + { + capabilities[indexes[i]] = orderedCapabilities[i]; + } + } + } + private static bool IsBuilderAlias(BuilderModel retainedBuilder, BuilderModel candidate) { if (string.Equals(retainedBuilder.TypeId, candidate.TypeId, StringComparison.Ordinal)) @@ -2688,6 +3038,13 @@ internal string GenerateCallbackTypeSignature(IReadOnlyList Promise<{returnType}>"; } + + private sealed class ExportedValueTreeNode + { + public Dictionary Children { get; } = new(StringComparer.Ordinal); + + public AtsExportedValueInfo? Value { get; set; } + } } /// diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 9361661e2b1..1e24c928c8a 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -96,6 +96,8 @@ public async Task SdkExportRestoresExactPackageAndWritesOnlyJsonToStdout() [Theory] [InlineData("1.2.3.4", "1.2.3.4")] [InlineData("1.2.3.0", "1.2.3")] + [InlineData("1.0.0.0-beta", "1.0.0-beta")] + [InlineData("1.2.3.4-preview.1+meta", "1.2.3.4-preview.1")] public async Task SdkExportRestoresNormalizedFourPartNuGetVersion(string requestedVersion, string normalizedVersion) { var interactionService = new TestInteractionService(); @@ -169,6 +171,9 @@ public async Task SdkExportDefaultsToCoreAtTheRunningSdkVersion() [InlineData("Contoso@not-a-version")] [InlineData("Contoso@13.5.*")] [InlineData("Contoso@[13.5.0]")] + [InlineData("Contoso@1.2.3.4-")] + [InlineData("Contoso@1.2.3.4+")] + [InlineData("Contoso@1.2.3.4-preview..1")] public async Task SdkExportRejectsMalformedOrNonExactPackages(string package) { var interactionService = new TestInteractionService(); @@ -254,6 +259,29 @@ public async Task SdkExportUsesStructuredInvalidParametersForUnsupportedLanguage error => error.Contains("klingon", StringComparison.Ordinal)); } + [Fact] + public async Task SdkExportRejectsLanguageWithoutCodeGeneratorBeforePreparation() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider( + interactionService, + out var workspace, + out var rpcClient, + out var project); + using var workspaceLease = workspace; + + var exitCode = await InvokeAsync(provider, "sdk export --language csharp"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Collection( + interactionService.DisplayedErrors, + error => Assert.Equal( + "SDK API export is not supported for C# (.NET) because it does not use a code generator.", + error)); + Assert.Equal(0, project.PrepareCallCount); + Assert.Null(rpcClient.LastExportRequest); + } + [Fact] public async Task SdkExportRpcFailureWritesNoPartialDocument() { @@ -386,6 +414,8 @@ private sealed class CapturingAppHostServerProject : IAppHostServerProject public IReadOnlyList Integrations { get; private set; } = []; + public int PrepareCallCount { get; private set; } + public string GetInstanceIdentifier() => AppDirectoryPath; public Task PrepareAsync( @@ -395,6 +425,7 @@ public Task PrepareAsync( string? packageSourceOverride = null, CancellationToken cancellationToken = default) { + PrepareCallCount++; Integrations = [.. integrations]; return Task.FromResult(new AppHostServerPrepareResult(Success: true, Output: null)); } diff --git a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs index 82d1e1e0a48..607b77cb7be 100644 --- a/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs +++ b/tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs @@ -1445,6 +1445,32 @@ public async Task PrepareAsync_WithPackageReferences_SetsOnlyPackageProbeManifes } } + [Fact] + public async Task PrepareAsync_WhenPackageRestoreIsCanceled_PropagatesCancellation() + { + using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); + using var cancellation = new CancellationTokenSource(); + var (server, executionFactory) = CreatePackageReferenceServer(workspace); + executionFactory.AsyncAttemptCallback = (_, _, cancellationToken) => + { + cancellation.Cancel(); + return Task.FromCanceled<(int ExitCode, string? Stdout)>(cancellationToken); + }; + var workingDirectory = GetWorkingDirectory(server); + + try + { + await Assert.ThrowsAnyAsync(() => server.PrepareAsync( + "13.2.0", + [IntegrationReference.FromPackage("Aspire.Hosting.Redis", "13.2.0")], + cancellationToken: cancellation.Token)); + } + finally + { + DeleteWorkingDirectory(workingDirectory); + } + } + [Fact] public async Task PrepareAsync_WithPackageReferences_UsesPackageSourceOverride() { diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 1d1e06681b5..ae972ad6c2d 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2377,6 +2377,118 @@ public void ApiExportIncludesCodeGeneratorIdentity() generator.GetProperty("version").GetString()); } + [Fact] + public void ApiExportIncludesExportedValuesWithGeneratedDeclaration() + { + var context = CreateContextFromTestAssembly(); + var generatedSource = _generator.GenerateDistributedApplication(context)["aspire.mts"]; + using var document = System.Text.Json.JsonDocument.Parse( + TypeScriptApiExportWriter.WriteToJson(ProjectApi(context, ApiExportPackageName))); + var items = document.RootElement.GetProperty("modules")[0].GetProperty("items").EnumerateArray(); + var testConfigs = Assert.Single( + items, + item => item.GetProperty("name").GetString() == "TestConfigs"); + + Assert.Equal("namespace", testConfigs.GetProperty("kind").GetString()); + Assert.Equal("export namespace TestConfigs", testConfigs.GetProperty("declaration").GetString()); + var defaultConfig = Assert.Single( + testConfigs.GetProperty("members").EnumerateArray(), + member => member.GetProperty("name").GetString() == "Default"); + const string expectedDeclaration = + "export const Default = { name: \"default\", port: 6379, enabled: true, optionalField: \"cache\" } as TestConfigDto"; + Assert.Equal("constant", defaultConfig.GetProperty("kind").GetString()); + Assert.Equal(expectedDeclaration, defaultConfig.GetProperty("declaration").GetString()); + Assert.Equal("The default test configuration.", defaultConfig.GetProperty("summary").GetString()); + Assert.Contains($"{expectedDeclaration};", generatedSource, StringComparison.Ordinal); + } + + [Fact] + public void ApiExportPromiseDeclarationContainsOnlySourcePromiseMembers() + { + var targetType = new AtsTypeRef + { + TypeId = $"{ApiExportPackageName}/PromiseContext", + Category = AtsTypeCategory.Handle + }; + var stringType = new AtsTypeRef + { + TypeId = AtsConstants.String, + Category = AtsTypeCategory.Primitive + }; + var voidType = new AtsTypeRef + { + TypeId = AtsConstants.Void, + Category = AtsTypeCategory.Primitive + }; + var context = CreateApiContext( + new AtsCapabilityInfo + { + CapabilityId = $"{ApiExportPackageName}/PromiseContext.readOnly.get", + MethodName = "readOnly", + OwningTypeName = "PromiseContext", + Parameters = [], + ReturnType = stringType, + TargetTypeId = targetType.TypeId, + TargetType = targetType, + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.PropertyGetter + }, + new AtsCapabilityInfo + { + CapabilityId = $"{ApiExportPackageName}/PromiseContext.mutable.get", + MethodName = "mutable", + OwningTypeName = "PromiseContext", + Parameters = [], + ReturnType = stringType, + TargetTypeId = targetType.TypeId, + TargetType = targetType, + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.PropertyGetter + }, + new AtsCapabilityInfo + { + CapabilityId = $"{ApiExportPackageName}/PromiseContext.mutable.set", + MethodName = "setMutable", + OwningTypeName = "PromiseContext", + Parameters = [new AtsParameterInfo { Name = "value", Type = stringType }], + ReturnType = voidType, + TargetTypeId = targetType.TypeId, + TargetType = targetType, + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.PropertySetter + }, + new AtsCapabilityInfo + { + CapabilityId = $"{ApiExportPackageName}/PromiseContext.run", + MethodName = "run", + OwningTypeName = "PromiseContext", + Parameters = [], + ReturnType = voidType, + TargetTypeId = targetType.TypeId, + TargetType = targetType, + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.InstanceMethod + }); + + var declaration = Assert.Single( + ProjectApi(context, ApiExportPackageName).Declarations, + declaration => declaration.Content.StartsWith( + "export interface PromiseContextPromise ", + StringComparison.Ordinal)); + const string expectedDeclaration = """ + export interface PromiseContextPromise extends PromiseLike { + readOnly(): Promise; + run(): PromiseContextPromise; + } + """; + + Assert.Equal(expectedDeclaration, declaration.Content); + Assert.Contains( + expectedDeclaration, + _generator.GenerateDistributedApplication(context)["aspire.mts"], + StringComparison.Ordinal); + } + [Fact] public void ApiReferenceExporterRequiresAndHonorsCancellation() { @@ -2490,6 +2602,79 @@ public void ApiExportEntrypointIdsIncludeTheOwningAssembly() Assert.Contains($"export async {first.Declaration} {{", generatedSource, StringComparison.Ordinal); } + [Fact] + public void ApiExportKeepsPackageLocalOptionsNamesAndCombinedGenerationIsDeterministic() + { + const string eventHubsPackage = "Aspire.Hosting.Azure.EventHubs"; + const string serviceBusPackage = "Aspire.Hosting.Azure.ServiceBus"; + var eventHubsCapability = CreateRunAsEmulatorCapability( + eventHubsPackage, + "DistributedApplicationBuilder", + new AtsTypeRef { TypeId = AtsConstants.String, Category = AtsTypeCategory.Primitive }); + var serviceBusCapability = CreateRunAsEmulatorCapability( + serviceBusPackage, + "DistributedApplicationBuilder", + new AtsTypeRef { TypeId = AtsConstants.Number, Category = AtsTypeCategory.Primitive }); + + var eventHubsModel = ProjectApi(CreateApiContext(eventHubsCapability), eventHubsPackage); + var serviceBusModel = ProjectApi(CreateApiContext(serviceBusCapability), serviceBusPackage); + var eventHubsOptions = Assert.Single( + eventHubsModel.Declarations, + declaration => declaration.Content.StartsWith("export interface RunAsEmulatorOptions ", StringComparison.Ordinal)); + var serviceBusOptions = Assert.Single( + serviceBusModel.Declarations, + declaration => declaration.Content.StartsWith("export interface RunAsEmulatorOptions ", StringComparison.Ordinal)); + + Assert.Equal( + (eventHubsPackage, ApiExportPackageVersion, $"{eventHubsPackage}:options:RunAsEmulatorOptions"), + (eventHubsModel.Package.Name, eventHubsModel.Package.Version, eventHubsOptions.Id)); + Assert.Equal( + (serviceBusPackage, ApiExportPackageVersion, $"{serviceBusPackage}:options:RunAsEmulatorOptions"), + (serviceBusModel.Package.Name, serviceBusModel.Package.Version, serviceBusOptions.Id)); + Assert.Contains( + "runAsEmulator(options?: RunAsEmulatorOptions)", + Assert.Single( + eventHubsModel.Modules.SelectMany(module => module.Items).SelectMany(item => item.Members), + member => member.CapabilityId == eventHubsCapability.CapabilityId).Declaration, + StringComparison.Ordinal); + Assert.Contains( + "runAsEmulator(options?: RunAsEmulatorOptions)", + Assert.Single( + serviceBusModel.Modules.SelectMany(module => module.Items).SelectMany(item => item.Members), + member => member.CapabilityId == serviceBusCapability.CapabilityId).Declaration, + StringComparison.Ordinal); + + var forwardContext = CreateApiContext(eventHubsCapability, serviceBusCapability); + var reverseContext = CreateApiContext(serviceBusCapability, eventHubsCapability); + var forwardSource = _generator.GenerateDistributedApplication(forwardContext)["aspire.mts"]; + var reverseSource = _generator.GenerateDistributedApplication(reverseContext)["aspire.mts"]; + Assert.Equal(forwardSource, reverseSource); + + var combinedPackage = new TypeScriptApiPackageIdentity("Aspire.Hosting.Combined", ApiExportPackageVersion); + var combinedAssemblies = new[] { eventHubsPackage, serviceBusPackage }; + var forwardModel = new TypeScriptApiProjector(forwardContext) + .BuildApiModel(combinedPackage, combinedAssemblies, CancellationToken.None); + var reverseModel = new TypeScriptApiProjector(reverseContext) + .BuildApiModel(combinedPackage, combinedAssemblies, CancellationToken.None); + Assert.Equal( + TypeScriptApiExportWriter.WriteToJson(forwardModel), + TypeScriptApiExportWriter.WriteToJson(reverseModel)); + + var methodsByCapability = forwardModel.Modules + .SelectMany(module => module.Items) + .SelectMany(item => item.Members) + .Where(member => member.CapabilityId is not null) + .ToDictionary(member => member.CapabilityId!, StringComparer.Ordinal); + Assert.Contains( + "options?: RunAsEmulatorOptions", + methodsByCapability[eventHubsCapability.CapabilityId].Declaration, + StringComparison.Ordinal); + Assert.Contains( + "options?: RunAsEmulator1Options", + methodsByCapability[serviceBusCapability.CapabilityId].Declaration, + StringComparison.Ordinal); + } + [Fact] public void ApiExportExplicitInterfaceMemberNameMatchesItsDeclaration() { @@ -2568,6 +2753,53 @@ private static TypeScriptApiModel ProjectApi(AtsContext context, string packageN [packageName], CancellationToken.None); + private static AtsContext CreateApiContext(params AtsCapabilityInfo[] capabilities) + => new() + { + Capabilities = capabilities, + HandleTypes = [], + DtoTypes = [], + EnumTypes = [], + ExportedValues = [], + Diagnostics = [] + }; + + private static AtsCapabilityInfo CreateRunAsEmulatorCapability( + string packageName, + string targetTypeName, + AtsTypeRef optionType) + { + var targetType = new AtsTypeRef + { + TypeId = $"Aspire.Hosting/{targetTypeName}", + Category = AtsTypeCategory.Handle + }; + + return new AtsCapabilityInfo + { + CapabilityId = $"{packageName}/runAsEmulator", + MethodName = "runAsEmulator", + Parameters = + [ + new AtsParameterInfo + { + Name = "configure", + Type = optionType, + IsOptional = true + } + ], + ReturnType = new AtsTypeRef + { + TypeId = AtsConstants.Void, + Category = AtsTypeCategory.Primitive + }, + TargetTypeId = targetType.TypeId, + TargetType = targetType, + ExpandedTargetTypes = [], + CapabilityKind = AtsCapabilityKind.InstanceMethod + }; + } + private static AtsContext CreateEntryPointContext(string packageName) { return new AtsContext From 22b5bc0d9bea917b78c0cf6f25bd2d8612ec7061 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 24 Aug 2026 19:02:16 -0400 Subject: [PATCH 70/73] Strengthen package export collision coverage Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5ddc8e81-7527-446e-97c0-d7db76bd6766 --- .../AtsTypeScriptCodeGeneratorTests.cs | 87 +++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index ae972ad6c2d..1d1d89fc55c 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -1231,6 +1231,12 @@ public void GenerateDistributedApplication_EveryReferencedPromiseWrapperIsDeclar private static readonly Regex s_promiseReferencePattern = new(@"\b[A-Z]\w*Promise(?:Impl)?\b", RegexOptions.Compiled); + private static readonly Regex s_apiDeclarationPattern = + new(@"\b(?:interface|enum|type)\s+([A-Z]\w*)\b", RegexOptions.Compiled); + + private static readonly Regex s_apiTypeReferencePattern = + new(@"\b[A-Z]\w*\b", RegexOptions.Compiled); + /// /// Removes line and block comments from generated TypeScript. Deliberately simple: generated /// code has no string literals containing comment delimiters. @@ -2610,11 +2616,19 @@ public void ApiExportKeepsPackageLocalOptionsNamesAndCombinedGenerationIsDetermi var eventHubsCapability = CreateRunAsEmulatorCapability( eventHubsPackage, "DistributedApplicationBuilder", - new AtsTypeRef { TypeId = AtsConstants.String, Category = AtsTypeCategory.Primitive }); + new AtsTypeRef + { + TypeId = $"{eventHubsPackage}/AzureEventHubsEmulatorResource", + Category = AtsTypeCategory.Handle + }); var serviceBusCapability = CreateRunAsEmulatorCapability( serviceBusPackage, "DistributedApplicationBuilder", - new AtsTypeRef { TypeId = AtsConstants.Number, Category = AtsTypeCategory.Primitive }); + new AtsTypeRef + { + TypeId = $"{serviceBusPackage}/AzureServiceBusEmulatorResource", + Category = AtsTypeCategory.Handle + }); var eventHubsModel = ProjectApi(CreateApiContext(eventHubsCapability), eventHubsPackage); var serviceBusModel = ProjectApi(CreateApiContext(serviceBusCapability), serviceBusPackage); @@ -2631,6 +2645,23 @@ public void ApiExportKeepsPackageLocalOptionsNamesAndCombinedGenerationIsDetermi Assert.Equal( (serviceBusPackage, ApiExportPackageVersion, $"{serviceBusPackage}:options:RunAsEmulatorOptions"), (serviceBusModel.Package.Name, serviceBusModel.Package.Version, serviceBusOptions.Id)); + Assert.Equal( + """ + export interface RunAsEmulatorOptions { + configure?: (emulator: AzureEventHubsEmulatorResourceHandle) => Promise; + } + """, + eventHubsOptions.Content); + Assert.Equal( + """ + export interface RunAsEmulatorOptions { + configure?: (emulator: AzureServiceBusEmulatorResourceHandle) => Promise; + } + """, + serviceBusOptions.Content); + Assert.NotEqual(eventHubsOptions.Content, serviceBusOptions.Content); + AssertApiDeclarationsAreSelfContained(eventHubsModel); + AssertApiDeclarationsAreSelfContained(serviceBusModel); Assert.Contains( "runAsEmulator(options?: RunAsEmulatorOptions)", Assert.Single( @@ -2753,6 +2784,34 @@ private static TypeScriptApiModel ProjectApi(AtsContext context, string packageN [packageName], CancellationToken.None); + private static void AssertApiDeclarationsAreSelfContained(TypeScriptApiModel model) + { + var completeSource = string.Join("\n", model.Declarations.Select(declaration => declaration.Content)); + var declared = s_apiDeclarationPattern.Matches(completeSource) + .Select(match => match.Groups[1].Value) + .ToHashSet(StringComparer.Ordinal); + + // The runtime declaration is a fixed compiler baseline. Scan every package-produced fragment + // after removing comments and branded-handle string literals so only TypeScript names remain. + var packageSource = string.Join( + "\n", + model.Declarations + .Where(declaration => declaration.Id != "aspire:runtime:base") + .Select(declaration => declaration.Content)); + var referenced = s_apiTypeReferencePattern.Matches(StripCommentsAndStringLiterals(packageSource)) + .Select(match => match.Value) + .ToHashSet(StringComparer.Ordinal); + + Assert.NotEmpty(declared); + Assert.NotEmpty(referenced); + referenced.ExceptWith(declared); + referenced.ExceptWith(["Promise", "PromiseLike"]); + Assert.True( + referenced.Count == 0, + $"Package '{model.Package.Name}' declarations reference type(s) that are never declared: " + + string.Join(", ", referenced.Order(StringComparer.Ordinal))); + } + private static AtsContext CreateApiContext(params AtsCapabilityInfo[] capabilities) => new() { @@ -2767,7 +2826,7 @@ private static AtsContext CreateApiContext(params AtsCapabilityInfo[] capabiliti private static AtsCapabilityInfo CreateRunAsEmulatorCapability( string packageName, string targetTypeName, - AtsTypeRef optionType) + AtsTypeRef callbackPayloadType) { var targetType = new AtsTypeRef { @@ -2784,8 +2843,26 @@ private static AtsCapabilityInfo CreateRunAsEmulatorCapability( new AtsParameterInfo { Name = "configure", - Type = optionType, - IsOptional = true + Type = new AtsTypeRef + { + TypeId = "callback", + Category = AtsTypeCategory.Callback + }, + IsOptional = true, + IsCallback = true, + CallbackParameters = + [ + new AtsCallbackParameterInfo + { + Name = "emulator", + Type = callbackPayloadType + } + ], + CallbackReturnType = new AtsTypeRef + { + TypeId = AtsConstants.Void, + Category = AtsTypeCategory.Primitive + } } ], ReturnType = new AtsTypeRef From 8d8f782ddd8af9d5a16f1f3313371dafbb9e531a Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 24 Aug 2026 19:57:26 -0400 Subject: [PATCH 71/73] Normalize TypeScript export test line endings Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5ddc8e81-7527-446e-97c0-d7db76bd6766 --- .../AtsTypeScriptCodeGeneratorTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 1d1d89fc55c..85ccf7d90a8 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2481,12 +2481,12 @@ public void ApiExportPromiseDeclarationContainsOnlySourcePromiseMembers() declaration => declaration.Content.StartsWith( "export interface PromiseContextPromise ", StringComparison.Ordinal)); - const string expectedDeclaration = """ + var expectedDeclaration = """ export interface PromiseContextPromise extends PromiseLike { readOnly(): Promise; run(): PromiseContextPromise; } - """; + """.ReplaceLineEndings("\n"); Assert.Equal(expectedDeclaration, declaration.Content); Assert.Contains( @@ -2650,14 +2650,14 @@ public void ApiExportKeepsPackageLocalOptionsNamesAndCombinedGenerationIsDetermi export interface RunAsEmulatorOptions { configure?: (emulator: AzureEventHubsEmulatorResourceHandle) => Promise; } - """, + """.ReplaceLineEndings("\n"), eventHubsOptions.Content); Assert.Equal( """ export interface RunAsEmulatorOptions { configure?: (emulator: AzureServiceBusEmulatorResourceHandle) => Promise; } - """, + """.ReplaceLineEndings("\n"), serviceBusOptions.Content); Assert.NotEqual(eventHubsOptions.Content, serviceBusOptions.Content); AssertApiDeclarationsAreSelfContained(eventHubsModel); From 90586da4734e415a734f8936af13f0cf97dd062e Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 24 Aug 2026 20:16:17 -0400 Subject: [PATCH 72/73] Reject incompatible generator package exports Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5ddc8e81-7527-446e-97c0-d7db76bd6766 --- docs/specs/cli-output-formats.md | 2 +- .../Commands/Sdk/SdkExportCommand.cs | 32 +++++++++++++----- .../Resources/ErrorStrings.Designer.cs | 9 +++++ src/Aspire.Cli/Resources/ErrorStrings.resx | 4 +++ .../Resources/xlf/ErrorStrings.cs.xlf | 5 +++ .../Resources/xlf/ErrorStrings.de.xlf | 5 +++ .../Resources/xlf/ErrorStrings.es.xlf | 5 +++ .../Resources/xlf/ErrorStrings.fr.xlf | 5 +++ .../Resources/xlf/ErrorStrings.it.xlf | 5 +++ .../Resources/xlf/ErrorStrings.ja.xlf | 5 +++ .../Resources/xlf/ErrorStrings.ko.xlf | 5 +++ .../Resources/xlf/ErrorStrings.pl.xlf | 5 +++ .../Resources/xlf/ErrorStrings.pt-BR.xlf | 5 +++ .../Resources/xlf/ErrorStrings.ru.xlf | 5 +++ .../Resources/xlf/ErrorStrings.tr.xlf | 5 +++ .../Resources/xlf/ErrorStrings.zh-Hans.xlf | 5 +++ .../Resources/xlf/ErrorStrings.zh-Hant.xlf | 5 +++ .../Commands/Sdk/SdkExportCommandTests.cs | 33 ++++++++++++++++--- 18 files changed, 132 insertions(+), 13 deletions(-) diff --git a/docs/specs/cli-output-formats.md b/docs/specs/cli-output-formats.md index 8b099b46d39..59d07ea8dfd 100644 --- a/docs/specs/cli-output-formats.md +++ b/docs/specs/cli-output-formats.md @@ -615,6 +615,6 @@ The top-level arrays are: ### `aspire sdk export` -`aspire sdk export --package Name@Version --language typescript` restores the exact package version and writes one canonical JSON document to standard output. Omit `--package` to export `Aspire.Hosting` at the running CLI's SDK version. Diagnostics are written to standard error. +`aspire sdk export --package Name@Version --language typescript` restores the exact integration package version and writes one canonical JSON document to standard output. Two package surfaces are tied to the running CLI: `Aspire.Hosting` can only be exported at the CLI's SDK version, and the selected language's code-generation package can only be exported at the generator version bundled with that CLI. Omit `--package` to export `Aspire.Hosting` at the running CLI's SDK version. Diagnostics are written to standard error. The top-level fields are `schemaVersion`, `language`, `generator`, `package`, `modules`, and `declarations`. The language exporter owns the schema; the CLI passes it through without reshaping it. diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index ecfe2188039..122e8f19939 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -124,15 +124,31 @@ protected override async Task ExecuteAsync(ParseResult parseResul languageInfo.LanguageId, cancellationToken); - if (codeGenerationPackage is not null && - !integrations.Any(integration => - integration.Name.Equals(codeGenerationPackage, StringComparison.OrdinalIgnoreCase))) + if (codeGenerationPackage is not null) { - // Match sdk generate: repository mode uses the generator from this checkout, while - // installed CLIs restore the package that accompanies their build. - integrations.Add(IntegrationReference.FromPackage( - codeGenerationPackage, - ExecutionContext.IdentityVersion)); + var requestedCodeGenerationPackage = integrations.FirstOrDefault(integration => + integration.Name.Equals(codeGenerationPackage, StringComparison.OrdinalIgnoreCase)); + if (requestedCodeGenerationPackage is not null && + !packageVersion.Equals(ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) + { + return CommandResult.Failure( + CliExitCodes.InvalidCommand, + string.Format( + CultureInfo.CurrentCulture, + ErrorStrings.SdkExportGeneratorPackageVersionMismatch, + codeGenerationPackage, + ExecutionContext.IdentitySdkVersion, + packageVersion)); + } + + if (requestedCodeGenerationPackage is null) + { + // Match sdk generate: repository mode uses the generator from this checkout, while + // installed CLIs restore the package that accompanies their build. + integrations.Add(IntegrationReference.FromPackage( + codeGenerationPackage, + ExecutionContext.IdentityVersion)); + } } } diff --git a/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs b/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs index 344f3672fa7..54d65fe1d1a 100644 --- a/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs +++ b/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs @@ -515,5 +515,14 @@ public static string SdkExportLanguageDoesNotSupportCodeGeneration { return ResourceManager.GetString("SdkExportLanguageDoesNotSupportCodeGeneration", resourceCulture); } } + + /// + /// Looks up a localized string similar to SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested.. + /// + public static string SdkExportGeneratorPackageVersionMismatch { + get { + return ResourceManager.GetString("SdkExportGeneratorPackageVersionMismatch", resourceCulture); + } + } } } diff --git a/src/Aspire.Cli/Resources/ErrorStrings.resx b/src/Aspire.Cli/Resources/ErrorStrings.resx index 8a52eee45a2..74ea3bc9e4e 100644 --- a/src/Aspire.Cli/Resources/ErrorStrings.resx +++ b/src/Aspire.Cli/Resources/ErrorStrings.resx @@ -302,4 +302,8 @@ SDK API export is not supported for {0} because it does not use a code generator. {0} is the AppHost language display name, for example "C# (.NET)". + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf index cc134fdf6d8..b301060b88d 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf @@ -267,6 +267,11 @@ Projekt neobsahuje hostitele aplikací Aspire. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf index c5a2f660488..86c8e493f31 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf @@ -267,6 +267,11 @@ Das Projekt enthält keinen Aspire-AppHost. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf index 4c028958ab3..dc5225e325b 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf @@ -267,6 +267,11 @@ El proyecto no contiene ningún apphost de Aspire. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf index 754375122b9..2b46f3a1bd9 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf @@ -267,6 +267,11 @@ Le projet ne contient pas d’Aspire AppHost. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf index 885cbf2922b..e0765a3215e 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf @@ -267,6 +267,11 @@ Il progetto non contiene un AppHost Aspire. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf index 7ad801d51ff..e208b0d05ea 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf @@ -267,6 +267,11 @@ プロジェクトに Aspire AppHost が含まれていません。 + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf index 83b17d1fca9..e8193140eab 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf @@ -267,6 +267,11 @@ 프로젝트에 Aspire AppHost가 포함되어 있지 않습니다. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf index 5a786c4fea0..be1ba64449c 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf @@ -267,6 +267,11 @@ Projekt nie zawiera hosta AppHost platformy Aspire. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf index 3545168624d..e7fce779b23 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf @@ -267,6 +267,11 @@ O projeto não contém um AppHost do Aspire. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf index a3c28d801bf..63b0bb7cc69 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf @@ -267,6 +267,11 @@ Проект не содержит хост приложений Aspire. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf index bc4381e7491..924bbf376cf 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf @@ -267,6 +267,11 @@ Proje bir Aspire AppHost içermiyor. + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf index 9a7a77a09ef..2acb9c699b7 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf @@ -267,6 +267,11 @@ 该项目不包含 Aspire 应用主机。 + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf index 41bd661bca6..974d269eeda 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf @@ -267,6 +267,11 @@ 該專案不包含 Aspire AppHost。 + + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. + {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + SDK API export is not supported for {0} because it does not use a code generator. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 1e24c928c8a..2fff6a7f58d 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -122,25 +122,50 @@ public async Task SdkExportRestoresNormalizedFourPartNuGetVersion(string request } [Fact] - public async Task SdkExportDoesNotAddTheRequestedGeneratorPackageTwice() + public async Task SdkExportRejectsRequestedGeneratorPackageAtDifferentVersion() + { + var interactionService = new TestInteractionService(); + using var provider = CreateProvider( + interactionService, + out var workspace, + out var rpcClient, + out var project, + identityVersion: "13.5.0"); + using var workspaceLease = workspace; + + var exitCode = await InvokeAsync( + provider, + "sdk export --language typescript --package Aspire.Hosting.CodeGeneration.TypeScript@13.4.0"); + + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Equal(0, project.PrepareCallCount); + Assert.Null(rpcClient.LastExportRequest); + Assert.Equal( + "SDK API export can only export Aspire.Hosting.CodeGeneration.TypeScript at 13.5.0 when that package supplies the selected language's code generator; 13.4.0 was requested.", + Assert.Single(interactionService.DisplayedErrors)); + } + + [Fact] + public async Task SdkExportUsesOneReferenceForRequestedGeneratorPackageAtCliVersion() { var interactionService = new TestInteractionService(); using var provider = CreateProvider( interactionService, out var workspace, out _, - out var project); + out var project, + identityVersion: "13.5.0"); using var workspaceLease = workspace; var exitCode = await InvokeAsync( provider, - "sdk export --language typescript --package Aspire.Hosting.CodeGeneration.TypeScript@2.0.0"); + "sdk export --language typescript --package Aspire.Hosting.CodeGeneration.TypeScript@13.5.0.0"); Assert.Equal(CliExitCodes.Success, exitCode); var package = Assert.Single( project.Integrations, integration => integration.Name == "Aspire.Hosting.CodeGeneration.TypeScript"); - Assert.Equal("[2.0.0]", package.Version); + Assert.Equal("[13.5.0]", package.Version); } [Fact] From 93cc33e0b151164fe2ee77b9ec653eb697e1337e Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 24 Aug 2026 20:54:35 -0400 Subject: [PATCH 73/73] Reject generator package API exports Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5ddc8e81-7527-446e-97c0-d7db76bd6766 --- docs/specs/cli-output-formats.md | 2 +- .../Commands/Sdk/SdkExportCommand.cs | 22 +++++++------------ .../Resources/ErrorStrings.Designer.cs | 6 ++--- src/Aspire.Cli/Resources/ErrorStrings.resx | 6 ++--- .../Resources/xlf/ErrorStrings.cs.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.de.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.es.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.fr.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.it.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.ja.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.ko.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.pl.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.pt-BR.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.ru.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.tr.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.zh-Hans.xlf | 8 +++---- .../Resources/xlf/ErrorStrings.zh-Hant.xlf | 8 +++---- .../Commands/Sdk/SdkExportCommandTests.cs | 17 +++++++------- .../AtsTypeScriptCodeGeneratorTests.cs | 2 +- 19 files changed, 77 insertions(+), 82 deletions(-) diff --git a/docs/specs/cli-output-formats.md b/docs/specs/cli-output-formats.md index 59d07ea8dfd..ffec04212ad 100644 --- a/docs/specs/cli-output-formats.md +++ b/docs/specs/cli-output-formats.md @@ -615,6 +615,6 @@ The top-level arrays are: ### `aspire sdk export` -`aspire sdk export --package Name@Version --language typescript` restores the exact integration package version and writes one canonical JSON document to standard output. Two package surfaces are tied to the running CLI: `Aspire.Hosting` can only be exported at the CLI's SDK version, and the selected language's code-generation package can only be exported at the generator version bundled with that CLI. Omit `--package` to export `Aspire.Hosting` at the running CLI's SDK version. Diagnostics are written to standard error. +`aspire sdk export --package Name@Version --language typescript` restores the exact integration package version and writes one canonical JSON document to standard output. `Aspire.Hosting` can only be exported at the CLI's SDK version. The selected language's code-generation package cannot be exported because it supplies the generator instead of an integration API surface. Omit `--package` to export `Aspire.Hosting` at the running CLI's SDK version. Diagnostics are written to standard error. The top-level fields are `schemaVersion`, `language`, `generator`, `package`, `modules`, and `declarations`. The language exporter owns the schema; the CLI passes it through without reshaping it. diff --git a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs index 122e8f19939..e6abd804453 100644 --- a/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs +++ b/src/Aspire.Cli/Commands/Sdk/SdkExportCommand.cs @@ -128,27 +128,21 @@ protected override async Task ExecuteAsync(ParseResult parseResul { var requestedCodeGenerationPackage = integrations.FirstOrDefault(integration => integration.Name.Equals(codeGenerationPackage, StringComparison.OrdinalIgnoreCase)); - if (requestedCodeGenerationPackage is not null && - !packageVersion.Equals(ExecutionContext.IdentitySdkVersion, StringComparison.OrdinalIgnoreCase)) + if (requestedCodeGenerationPackage is not null) { return CommandResult.Failure( CliExitCodes.InvalidCommand, string.Format( CultureInfo.CurrentCulture, - ErrorStrings.SdkExportGeneratorPackageVersionMismatch, - codeGenerationPackage, - ExecutionContext.IdentitySdkVersion, - packageVersion)); + ErrorStrings.SdkExportGeneratorPackageNotExportable, + codeGenerationPackage)); } - if (requestedCodeGenerationPackage is null) - { - // Match sdk generate: repository mode uses the generator from this checkout, while - // installed CLIs restore the package that accompanies their build. - integrations.Add(IntegrationReference.FromPackage( - codeGenerationPackage, - ExecutionContext.IdentityVersion)); - } + // Match sdk generate: repository mode uses the generator from this checkout, while + // installed CLIs restore the package that accompanies their build. + integrations.Add(IntegrationReference.FromPackage( + codeGenerationPackage, + ExecutionContext.IdentityVersion)); } } diff --git a/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs b/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs index 54d65fe1d1a..5ac9a62950e 100644 --- a/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs +++ b/src/Aspire.Cli/Resources/ErrorStrings.Designer.cs @@ -517,11 +517,11 @@ public static string SdkExportLanguageDoesNotSupportCodeGeneration { } /// - /// Looks up a localized string similar to SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested.. + /// Looks up a localized string similar to SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface.. /// - public static string SdkExportGeneratorPackageVersionMismatch { + public static string SdkExportGeneratorPackageNotExportable { get { - return ResourceManager.GetString("SdkExportGeneratorPackageVersionMismatch", resourceCulture); + return ResourceManager.GetString("SdkExportGeneratorPackageNotExportable", resourceCulture); } } } diff --git a/src/Aspire.Cli/Resources/ErrorStrings.resx b/src/Aspire.Cli/Resources/ErrorStrings.resx index 74ea3bc9e4e..63240d12ffd 100644 --- a/src/Aspire.Cli/Resources/ErrorStrings.resx +++ b/src/Aspire.Cli/Resources/ErrorStrings.resx @@ -302,8 +302,8 @@ SDK API export is not supported for {0} because it does not use a code generator. {0} is the AppHost language display name, for example "C# (.NET)". - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf index b301060b88d..aeece100574 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.cs.xlf @@ -267,10 +267,10 @@ Projekt neobsahuje hostitele aplikací Aspire. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf index 86c8e493f31..35a10b30774 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.de.xlf @@ -267,10 +267,10 @@ Das Projekt enthält keinen Aspire-AppHost. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf index dc5225e325b..6efed983274 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.es.xlf @@ -267,10 +267,10 @@ El proyecto no contiene ningún apphost de Aspire. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf index 2b46f3a1bd9..6649f8da730 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.fr.xlf @@ -267,10 +267,10 @@ Le projet ne contient pas d’Aspire AppHost. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf index e0765a3215e..c5463103b6a 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.it.xlf @@ -267,10 +267,10 @@ Il progetto non contiene un AppHost Aspire. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf index e208b0d05ea..bb771c98ef2 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ja.xlf @@ -267,10 +267,10 @@ プロジェクトに Aspire AppHost が含まれていません。 - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf index e8193140eab..6f7fb16bb28 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ko.xlf @@ -267,10 +267,10 @@ 프로젝트에 Aspire AppHost가 포함되어 있지 않습니다. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf index be1ba64449c..b063951886d 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pl.xlf @@ -267,10 +267,10 @@ Projekt nie zawiera hosta AppHost platformy Aspire. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf index e7fce779b23..185a2c706f9 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.pt-BR.xlf @@ -267,10 +267,10 @@ O projeto não contém um AppHost do Aspire. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf index 63b0bb7cc69..e75d77e357c 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.ru.xlf @@ -267,10 +267,10 @@ Проект не содержит хост приложений Aspire. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf index 924bbf376cf..b1fc5eb5e35 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.tr.xlf @@ -267,10 +267,10 @@ Proje bir Aspire AppHost içermiyor. - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf index 2acb9c699b7..db6e0a72688 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hans.xlf @@ -267,10 +267,10 @@ 该项目不包含 Aspire 应用主机。 - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf index 974d269eeda..130e527db2a 100644 --- a/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf +++ b/src/Aspire.Cli/Resources/xlf/ErrorStrings.zh-Hant.xlf @@ -267,10 +267,10 @@ 該專案不包含 Aspire AppHost。 - - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - SDK API export can only export {0} at {1} when that package supplies the selected language's code generator; {2} was requested. - {0} is the code-generation package name. {1} is the version bundled with the running CLI. {2} is the requested package version. + + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + SDK API export cannot export {0} because that package supplies the selected language's code generator instead of an integration API surface. + {0} is the code-generation package name. SDK API export is not supported for {0} because it does not use a code generator. diff --git a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs index 2fff6a7f58d..72c2bf6d594 100644 --- a/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/Sdk/SdkExportCommandTests.cs @@ -141,18 +141,18 @@ public async Task SdkExportRejectsRequestedGeneratorPackageAtDifferentVersion() Assert.Equal(0, project.PrepareCallCount); Assert.Null(rpcClient.LastExportRequest); Assert.Equal( - "SDK API export can only export Aspire.Hosting.CodeGeneration.TypeScript at 13.5.0 when that package supplies the selected language's code generator; 13.4.0 was requested.", + "SDK API export cannot export Aspire.Hosting.CodeGeneration.TypeScript because that package supplies the selected language's code generator instead of an integration API surface.", Assert.Single(interactionService.DisplayedErrors)); } [Fact] - public async Task SdkExportUsesOneReferenceForRequestedGeneratorPackageAtCliVersion() + public async Task SdkExportRejectsRequestedGeneratorPackageAtCliVersion() { var interactionService = new TestInteractionService(); using var provider = CreateProvider( interactionService, out var workspace, - out _, + out var rpcClient, out var project, identityVersion: "13.5.0"); using var workspaceLease = workspace; @@ -161,11 +161,12 @@ public async Task SdkExportUsesOneReferenceForRequestedGeneratorPackageAtCliVers provider, "sdk export --language typescript --package Aspire.Hosting.CodeGeneration.TypeScript@13.5.0.0"); - Assert.Equal(CliExitCodes.Success, exitCode); - var package = Assert.Single( - project.Integrations, - integration => integration.Name == "Aspire.Hosting.CodeGeneration.TypeScript"); - Assert.Equal("[13.5.0]", package.Version); + Assert.Equal(CliExitCodes.InvalidCommand, exitCode); + Assert.Equal(0, project.PrepareCallCount); + Assert.Null(rpcClient.LastExportRequest); + Assert.Equal( + "SDK API export cannot export Aspire.Hosting.CodeGeneration.TypeScript because that package supplies the selected language's code generator instead of an integration API surface.", + Assert.Single(interactionService.DisplayedErrors)); } [Fact] diff --git a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs index 85ccf7d90a8..40a3b4e94a9 100644 --- a/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs +++ b/tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs @@ -2491,7 +2491,7 @@ export interface PromiseContextPromise extends PromiseLike { Assert.Equal(expectedDeclaration, declaration.Content); Assert.Contains( expectedDeclaration, - _generator.GenerateDistributedApplication(context)["aspire.mts"], + _generator.GenerateDistributedApplication(context)["aspire.mts"].ReplaceLineEndings("\n"), StringComparison.Ordinal); }