| File: src\Shared\Model\Serialization\ResourceJson.cs | Web Access |
| Project: src\src\Aspire.Cli\Aspire.Cli.csproj (aspire) |
// 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.Nodes; using System.Text.Json.Serialization; namespace Aspire.Shared.Model.Serialization; /// <summary> /// Represents a resource in JSON format. /// This is a shared representation used by both the Dashboard and CLI. /// </summary> // `aspire describe --format json` uses this shape and the nested resource shapes below; // keep docs/specs/cli-output-formats.md in sync when changing them. internal sealed class ResourceJson { /// <summary> /// The name of the resource. /// </summary> public string? Name { get; set; } /// <summary> /// The display name of the resource. /// </summary> public string? DisplayName { get; set; } /// <summary> /// The type of the resource. /// </summary> public string? ResourceType { get; set; } /// <summary> /// The unique identifier of the resource. /// </summary> public string? Uid { get; set; } /// <summary> /// The state of the resource. /// </summary> public string? State { get; set; } /// <summary> /// The display names of resources this resource is waiting for. /// </summary> public string[]? WaitingFor { get; set; } /// <summary> /// The state style hint (e.g., "success", "error", "warning"). /// </summary> public string? StateStyle { get; set; } /// <summary> /// The creation timestamp of the resource. /// </summary> public DateTimeOffset? CreationTimestamp { get; set; } /// <summary> /// The start timestamp of the resource. /// </summary> public DateTimeOffset? StartTimestamp { get; set; } /// <summary> /// The stop timestamp of the resource. /// </summary> public DateTimeOffset? StopTimestamp { get; set; } /// <summary> /// The source of the resource (e.g., project path, container image, executable path). /// </summary> public string? Source { get; set; } /// <summary> /// The exit code if the resource has exited. /// </summary> public int? ExitCode { get; set; } /// <summary> /// The health status of the resource. /// </summary> public string? HealthStatus { get; set; } /// <summary> /// The URL to the resource in the Aspire Dashboard. /// </summary> public string? DashboardUrl { get; set; } /// <summary> /// The relationships of the resource. /// </summary> public ResourceRelationshipJson[]? Relationships { get; set; } /// <summary> /// The URLs/endpoints associated with the resource. /// </summary> public ResourceUrlJson[]? Urls { get; set; } /// <summary> /// The volumes associated with the resource. /// </summary> public ResourceVolumeJson[]? Volumes { get; set; } /// <summary> /// The properties of the resource. /// Dictionary key is the property name, value is the property value. /// </summary> public Dictionary<string, JsonNode?>? Properties { get; set; } /// <summary> /// The environment variables associated with the resource. /// Dictionary key is the environment variable name, value is the environment variable value. /// </summary> public Dictionary<string, string?>? Environment { get; set; } /// <summary> /// The health reports associated with the resource. /// Dictionary key is the health report name. /// </summary> public Dictionary<string, ResourceHealthReportJson>? HealthReports { get; set; } /// <summary> /// The commands available for the resource. /// Dictionary key is the command name. /// </summary> public Dictionary<string, ResourceCommandJson>? Commands { get; set; } } /// <summary> /// Represents a URL/endpoint in JSON format. /// </summary> internal sealed class ResourceUrlJson { /// <summary> /// The name of the endpoint. /// </summary> public string? Name { get; set; } /// <summary> /// The display name of the URL. /// </summary> public string? DisplayName { get; set; } /// <summary> /// The URL value. /// </summary> public string? Url { get; set; } /// <summary> /// Whether this is an internal endpoint. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public bool IsInternal { get; set; } } /// <summary> /// Represents a volume in JSON format. /// </summary> internal sealed class ResourceVolumeJson { /// <summary> /// The source path of the volume. /// </summary> public string? Source { get; set; } /// <summary> /// The target path of the volume. /// </summary> public string? Target { get; set; } /// <summary> /// The mount type of the volume. /// </summary> public string? MountType { get; set; } /// <summary> /// Whether the volume is read-only. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public bool IsReadOnly { get; set; } } /// <summary> /// Represents a health report in JSON format. /// </summary> internal sealed class ResourceHealthReportJson { /// <summary> /// The health status. /// </summary> public string? Status { get; set; } /// <summary> /// The description of the health report. /// </summary> public string? Description { get; set; } /// <summary> /// The exception message if any. /// </summary> public string? ExceptionMessage { get; set; } } /// <summary> /// Represents a relationship in JSON format. /// </summary> internal sealed class ResourceRelationshipJson { /// <summary> /// The type of the relationship. /// </summary> public string? Type { get; set; } /// <summary> /// The name of the related resource. /// </summary> public string? ResourceName { get; set; } } /// <summary> /// Represents a command in JSON format. /// </summary> internal sealed class ResourceCommandJson { /// <summary> /// The display name of the command. /// </summary> public string? DisplayName { get; set; } /// <summary> /// The description of the command. /// </summary> public string? Description { get; set; } /// <summary> /// Where the command is visible. Omitted when the command uses the default UI and API visibility. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Visibility { get; set; } /// <summary> /// The state of the command (e.g., "Enabled", "Disabled", "Hidden"). /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? State { get; set; } /// <summary> /// The sort order of the command for display purposes. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? SortOrder { get; set; } /// <summary> /// The ordered inputs that describe the invocation arguments accepted by the command. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ResourceCommandArgumentJson[]? ArgumentInputs { get; set; } } /// <summary> /// Constants for resource command state values in serialized resource JSON. /// </summary> internal static class KnownCommandState { public const string Enabled = "Enabled"; public const string Disabled = "Disabled"; public const string Hidden = "Hidden"; } /// <summary> /// Represents a command invocation argument input in JSON format. /// Keep this contract in sync with the VS Code extension's ResourceCommandArgumentInputJson /// in extension/src/views/AppHostDataRepository.ts. /// </summary> internal sealed class ResourceCommandArgumentJson { /// <summary> /// The argument name. /// </summary> public required string Name { get; set; } /// <summary> /// The display label. /// </summary> public string? Label { get; set; } /// <summary> /// The argument description. /// </summary> public string? Description { get; set; } /// <summary> /// Whether the description should be rendered as Markdown. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public bool EnableDescriptionMarkdown { get; set; } /// <summary> /// The input type. /// </summary> public required string InputType { get; set; } /// <summary> /// Whether the argument is required. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public bool Required { get; set; } /// <summary> /// The placeholder text. /// </summary> public string? Placeholder { get; set; } /// <summary> /// The default value. /// </summary> public string? Value { get; set; } /// <summary> /// Choice options keyed by submitted value. /// </summary> public Dictionary<string, string?>? Options { get; set; } /// <summary> /// Whether custom choices are allowed. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public bool AllowCustomChoice { get; set; } /// <summary> /// Whether the argument input is disabled. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public bool Disabled { get; set; } /// <summary> /// The maximum length for text inputs. /// </summary> public int? MaxLength { get; set; } /// <summary> /// Dynamic input loading metadata. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ResourceCommandArgumentDynamicLoadingJson? DynamicLoading { get; set; } } /// <summary> /// Represents dynamic loading metadata for a command invocation argument input in JSON format. /// Keep this contract in sync with the VS Code extension's ResourceCommandArgumentDynamicLoadingJson /// in extension/src/views/AppHostDataRepository.ts. /// </summary> internal sealed class ResourceCommandArgumentDynamicLoadingJson { /// <summary> /// Whether the input should always load when prompting starts. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public bool AlwaysLoadOnStart { get; set; } /// <summary> /// Input names that trigger reloading when their values change. /// </summary> [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string[]? DependsOnInputs { get; set; } }