Use mts for TypeScript AppHosts#16984
Conversation
Generate TypeScript AppHost SDK files as .mts with .mjs import specifiers while keeping generated files under .modules. Scaffold new TypeScript AppHosts as apphost.mts and preserve legacy apphost.ts projects by emitting legacy .ts SDK files when needed. Update templates, playgrounds, polyglot fixtures, snapshots, and focused tests for the new TypeScript AppHost shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16984Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16984" |
…ypescript-codegen
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ypescript-codegen
There was a problem hiding this comment.
Pull request overview
This PR updates Aspire’s TypeScript AppHost ecosystem to use explicit ESM by default (apphost.mts + .mjs imports), while keeping legacy apphost.ts projects working and making aspire init safer for brownfield JS/TS repos by scaffolding a nested aspire-apphost/ package.
Changes:
- Switch TypeScript AppHost templates/fixtures to
apphost.mtsand update imports to./.modules/*.mjs. - Generate TypeScript SDK output as
.mtsfor new AppHosts, while converting back to.ts+.jsspecifiers for legacyapphost.tsprojects. - Add brownfield behavior for JS/TS repos: scaffold into
aspire-apphost/, add root delegate scripts, and adjust pnpm install behavior for nested packages.
Reviewed changes
Copilot reviewed 229 out of 229 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/PolyglotAppHosts/Aspire.Hosting/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting/TypeScript/apphost.mts | Switch SDK imports to .mjs; update validation filename. |
| tests/PolyglotAppHosts/Aspire.Hosting.Yarp/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Yarp/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Yarp/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Valkey/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Valkey/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Valkey/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.SqlServer/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.SqlServer/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.SqlServer/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Seq/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Seq/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Seq/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Redis/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Redis/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Redis/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.RabbitMQ/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.RabbitMQ/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.RabbitMQ/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Qdrant/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Qdrant/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Qdrant/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Python/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Python/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Python/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.PostgreSQL/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.PostgreSQL/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.PostgreSQL/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Orleans/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Orleans/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Orleans/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Oracle/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Oracle/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Oracle/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.OpenAI/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.OpenAI/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.OpenAI/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Nats/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Nats/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Nats/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.MySql/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.MySql/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.MySql/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.MongoDB/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.MongoDB/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.MongoDB/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Milvus/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Milvus/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Milvus/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Maui/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Maui/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Maui/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Kubernetes/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Kubernetes/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Kubernetes/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Keycloak/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Keycloak/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Keycloak/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Kafka/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Kafka/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Kafka/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.JavaScript/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.JavaScript/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.JavaScript/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Go/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Go/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Go/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.GitHub.Models/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.GitHub.Models/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.GitHub.Models/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Garnet/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Garnet/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Garnet/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Foundry/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Foundry/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Foundry/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Docker/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Docker/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Docker/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.DevTunnels/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.DevTunnels/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.DevTunnels/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/TypeScript/apphost.mts | Switch SDK/base imports to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.SignalR/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.SignalR/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.SignalR/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Redis/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Redis/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Redis/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.PostgreSQL/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.PostgreSQL/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.PostgreSQL/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Network/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Network/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Network/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Kusto/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Kusto/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Kusto/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Functions/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Functions/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.Functions/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppService/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppService/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppService/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppContainers/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppContainers/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppContainers/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppConfiguration/TypeScript/tsconfig.json | Update includes for .mts + generated SDK. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppConfiguration/TypeScript/aspire.config.json | Point AppHost path to apphost.mts. |
| tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppConfiguration/TypeScript/apphost.mts | Switch SDK import to .mjs. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/TypeScriptLanguageSupportTests.cs | Update scaffolding expectations for .mts + nested package rules. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts | Snapshot updates for .mts + .mjs imports. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/transport.verified.ts | Snapshot header updated to .mts. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/base.verified.ts | Snapshot updates for .mts + .mjs imports. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts | Snapshot updates for .mts + .mjs imports. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs | Update generated file names to .mts. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.JsTests/vitest.config.ts | Update resource aliases to .mts. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.JsTests/tsconfig.json | Update paths/includes to .mts. |
| tests/Aspire.Deployment.EndToEnd.Tests/TypeScriptVnetSqlServerInfraDeploymentTests.cs | Update test to edit apphost.mts. |
| tests/Aspire.Deployment.EndToEnd.Tests/TypeScriptExpressDeploymentTests.cs | Update test to edit apphost.mts. |
| tests/Aspire.Deployment.EndToEnd.Tests/PythonFastApiDeploymentTests.cs | Update test to edit apphost.mts. |
| tests/Aspire.Deployment.EndToEnd.Tests/AppServicePythonDeploymentTests.cs | Update test to edit apphost.mts. |
| tests/Aspire.Deployment.EndToEnd.Tests/AcrPurgeTaskDeploymentTests.cs | Update test to edit apphost.mts. |
| tests/Aspire.Cli.Tests/TestServices/TestTypeScriptStarterProjectFactory.cs | Recognize both apphost.mts and legacy apphost.ts. |
| tests/Aspire.Cli.Tests/Scaffolding/ScaffoldingServiceTests.cs | Add unit tests for nested brownfield scaffolding + package.json serialization. |
| tests/Aspire.Cli.Tests/Scaffolding/PackageJsonMergerTests.cs | Add test for dependency/devDependency dedup behavior. |
| tests/Aspire.Cli.Tests/Projects/TypeScriptAppHostToolchainResolverTests.cs | Update watch extensions and pnpm install args. |
| tests/Aspire.Cli.Tests/Projects/GuestAppHostProjectTests.cs | Add test for legacy TS SDK conversion (.mts→.ts). |
| tests/Aspire.Cli.Tests/Projects/DefaultLanguageDiscoveryTests.cs | Update TypeScript defaults to .mts while keeping .ts detection. |
| tests/Aspire.Cli.Tests/Commands/TypeScriptAppHostToolingCheckTests.cs | Update detection to .mts. |
| tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs | Update TypeScript starter expectations (but see review comment). |
| tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs | Update init behavior for .mts + legacy/brownfield handling. |
| tests/Aspire.Cli.EndToEnd.Tests/TypeScriptStarterTemplateTests.cs | Expect generated SDK file aspire.mts. |
| tests/Aspire.Cli.EndToEnd.Tests/TypeScriptSqlServerNativeAssetsBundleTests.cs | Expect apphost.mts and .mjs imports. |
| tests/Aspire.Cli.EndToEnd.Tests/TypeScriptReusablePackageTests.cs | Update reusable-package test to .mts/.mjs. |
| tests/Aspire.Cli.EndToEnd.Tests/TypeScriptPublishTests.cs | Update publish tests to apphost.mts and .mjs. |
| tests/Aspire.Cli.EndToEnd.Tests/TypeScriptPolyglotTests.cs | Update brownfield nesting assertions and paths. |
| tests/Aspire.Cli.EndToEnd.Tests/TypeScriptCodegenValidationTests.cs | Update expected generated files to .mts. |
| tests/Aspire.Cli.EndToEnd.Tests/SmokeTests.cs | Read stable AppHost path from config (.ts or .mts). |
| tests/Aspire.Cli.EndToEnd.Tests/SecretTypeScriptAppHostTests.cs | Use --apphost apphost.mts. |
| tests/Aspire.Cli.EndToEnd.Tests/ProjectReferenceTests.cs | Update wiring and grep to .mts. |
| tests/Aspire.Cli.EndToEnd.Tests/LocalConfigMigrationTests.cs | Update legacy migration assertions to .mts. |
| tests/Aspire.Cli.EndToEnd.Tests/KubernetesDeployTypeScriptTests.cs | Update test to edit apphost.mts. |
| tests/Aspire.Cli.EndToEnd.Tests/JavaScriptPublishTests.cs | Update init expectation to apphost.mts. |
| tests/Aspire.Cli.EndToEnd.Tests/Helpers/TypeScriptAppHostToolchainTestHelpers.cs | Add helper to detect corepack toolchains. |
| tests/Aspire.Cli.EndToEnd.Tests/DoctorCommandTests.cs | Prepare corepack toolchains before PATH checks. |
| tests/Aspire.Cli.EndToEnd.Tests/ConfigDiscoveryTests.cs | Expect apphost.mts in config discovery. |
| tests/Aspire.Cli.EndToEnd.Tests/ChannelUpdateWorkflowTests.cs | Read appHost path from config and select .mjs import accordingly. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptLanguageSupport.cs | Default AppHost name .mts; add brownfield package naming; extend detection. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/transport.mts | Rename embedded transport resource to .mts. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.mts | Rename embedded base resource to .mts + .mjs imports. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs | Emit .mts files and .mjs specifiers. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/Aspire.Hosting.CodeGeneration.TypeScript.csproj | Embed .mts resources instead of .ts. |
| src/Aspire.Cli/Templating/Templates/ts-starter/tsconfig.apphost.json | Update includes for apphost.mts + .mts SDK files. |
| src/Aspire.Cli/Templating/Templates/ts-starter/package.json | Update lint script to apphost.mts. |
| src/Aspire.Cli/Templating/Templates/ts-starter/eslint.config.mjs | Target apphost.mts. |
| src/Aspire.Cli/Templating/Templates/ts-starter/aspire.config.json | Point AppHost path to apphost.mts. |
| src/Aspire.Cli/Templating/Templates/ts-starter/apphost.mts | Switch SDK import to .mjs. |
| src/Aspire.Cli/Templating/Templates/ts-starter/.gitignore | Template change (ignore formatting). |
| src/Aspire.Cli/Templating/Templates/py-starter/tsconfig.apphost.json | Update includes for apphost.mts + .mts SDK files. |
| src/Aspire.Cli/Templating/Templates/py-starter/package.json | Update lint script to apphost.mts. |
| src/Aspire.Cli/Templating/Templates/py-starter/eslint.config.mjs | Target apphost.mts. |
| src/Aspire.Cli/Templating/Templates/py-starter/aspire.config.json | Point AppHost path to apphost.mts. |
| src/Aspire.Cli/Templating/Templates/py-starter/apphost.mts | Switch SDK import to .mjs. |
| src/Aspire.Cli/Templating/Templates/py-starter/.gitignore | Template change (ignore formatting). |
| src/Aspire.Cli/Templating/CliTemplateFactory.TypeScriptStarterTemplate.cs | Find TS AppHost as apphost.mts. |
| src/Aspire.Cli/Templating/CliTemplateFactory.PythonStarterTemplate.cs | Find TS AppHost as apphost.mts. |
| src/Aspire.Cli/Scaffolding/ScaffoldingService.cs | Add nested brownfield scaffolding + root delegate script injection. |
| src/Aspire.Cli/Scaffolding/PackageJsonMerger.cs | Avoid duplicating deps across dependencies/devDependencies. |
| src/Aspire.Cli/Projects/TypeScriptAppHostToolchainResolver.cs | Watch .mts; pnpm nested install --ignore-workspace. |
| src/Aspire.Cli/Projects/ILanguageDiscovery.cs | Clarify docs; keep generated folder .modules. |
| src/Aspire.Cli/Projects/GuestAppHostProject.cs | Convert generated .mts back to legacy .ts for apphost.ts projects. |
| src/Aspire.Cli/Projects/DefaultLanguageDiscovery.cs | Default TypeScript AppHost to apphost.mts + detect legacy .ts. |
| src/Aspire.Cli/Commands/InitCommand.cs | Skip when legacy AppHost exists; display nested created path. |
| playground/TypeScriptApps/RpsArena/tsconfig.json | Update includes for .mts SDK files. |
| playground/TypeScriptApps/RpsArena/aspire.config.json | Point AppHost path to apphost.mts. |
| playground/TypeScriptApps/RpsArena/apphost.mts | Switch SDK import to .mjs. |
| playground/TypeScriptApps/AzureFunctionsSample/aspire.config.json | Point AppHost path to apphost.mts. |
| playground/TypeScriptApps/AzureFunctionsSample/AppHost/tsconfig.json | Update includes for .mts SDK files. |
| playground/TypeScriptApps/AzureFunctionsSample/AppHost/apphost.mts | Switch SDK import to .mjs. |
| playground/TypeScriptAppHost/tsconfig.json | Update includes for .mts SDK files. |
| playground/TypeScriptAppHost/aspire.config.json | Point AppHost path to apphost.mts. |
| playground/TypeScriptAppHost/apphost.mts | Switch SDK import to .mjs. |
| playground/TypeScriptAppHost/.vscode/launch.json | Update debug program to apphost.mts. |
| .github/workflows/polyglot-validation/test-typescript.sh | Update workflow script to edit/run apphost.mts. |
| .github/workflows/polyglot-validation/test-typescript-playground.sh | Update workflow restore to use --apphost apphost.mts. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
I am not loving this mts thing, I dunno why but it feels not great. Does pulumi do this? |
|
@DamianEdwards help! David is questioning this PR, we need your expertize. |
|
RE Plugin they seem to have a bunch of docs about this: https://www.pulumi.com/docs/iac/languages-sdks/javascript/#native-esm-support |
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
Matched test failure patterns (1 test)
|
|
This needs a pr-testing report. |
|
Took this for a spin against the PR build. CLI / installInstalled the PR build at Dynamic validation against
|
| Check | Result |
|---|---|
aspire new aspire-ts-starter produces apphost.mts (not apphost.ts) |
✅ |
aspire.config.json → "path": "apphost.mts" |
✅ |
tsconfig.apphost.json include lists apphost.mts + .modules/{aspire,base,transport}.mts |
✅ |
package.json lint script targets apphost.mts |
✅ |
apphost.mts imports use .mjs (e.g. ./.modules/aspire.mjs) per ESM |
✅ |
Codegen .modules/ regenerates as .mts after aspire restore against PR SDK |
✅ |
tsc --noEmit -p tsconfig.apphost.json post-restore |
✅ exit 0 |
aspire run smoke against the starter |
✅ apphost launched, dashboard reports "AppHost: apphost.mts" |
One thing worth confirming
Out of the box, aspire new aspire-ts-empty still produces apphost.ts (not .mts) and .modules/*.ts. After aspire restore against the PR SDK the user's .modules/ files regenerate as .mts correctly, so this looks like an artifact of the empty template's bundled SDK pin (stable 13.3.3). Just wanted to flag — is the plan for the post-release SDK bump to naturally pull this forward, or does the empty template need an explicit refresh before merge? Not blocking, just want to make sure nobody chases their tail debugging the gap later.
Code review
Walked the diff: detection patterns (["apphost.mts", "apphost.ts"] with .mts first), DropPolyglotSkeletonAsync not clobbering existing .ts, brownfield nesting under aspire-apphost/, legacy emit via ShouldEmitLegacyTypeScriptGeneratedFiles, and the healing/idempotent write in ProjectLocator.cs — all looked correct and internally consistent. No bugs/security/logic concerns from me.
LGTM for the migration itself; just the ts-empty question above.
|
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…sebastienros/sebros-typescript-codegen
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Supporting this change —
|
| File extension | Module format determined by |
|---|---|
.ts / .js |
The nearest package.json "type" field |
.mts / .mjs |
Always ESM — package.json is ignored |
.cts / .cjs |
Always CJS — package.json is ignored |
So .ts is the extension whose meaning depends on the user's project. .mts is the extension whose meaning is independent of what we don't know about the user's project. For a brownfield-safe scaffold, .mts is precisely the right primitive.
This isn't a TypeScript design quirk — it mirrors the underlying Node.js spec for .mjs / .cjs, and is exactly the case .mts was added to handle in TypeScript 4.7. From the TS 4.7 release notes:
"The
typefield inpackage.jsonis nice because it allows us to continue using the.tsand.jsfile extensions which can be convenient; however, you will occasionally need to write a file that differs from whattypespecifies. You might also just prefer to always be explicit."
And from the Choosing Compiler Options guide:
"Remember to set
"type": "module"or use.mtsfiles if you intend to emit ES modules."
Why .ts doesn't work here
The AppHost code uses top-level await:
const builder = await createBuilder();
// ...
await builder.build().run();Top-level await is ESM-only. There are exactly three ways to make this work:
- Set
"type": "module"in the user's existingpackage.json. This is what CLI: TypeScript AppHost top-level await fails in brownfield repos without type:module #16124 specifically calls out as breaking — the excalidraw repro has 11+ build scripts usingrequire()that immediately break the moment the package becomes ESM. This is more brownfield-hostile than the.mtsrename. - Wrap the AppHost body in an async IIFE. Works mechanically, but it's hand-written boilerplate every user has to maintain, and it doesn't help if anyone ever wants
import.metaor other ESM features. - Use
.mts. Node guarantees ESM semantics for this file regardless of the surroundingpackage.json. The user's existing CJS scripts keep working. The AppHost works. No mutation of the user's"type"field.
Option 3 is what this PR does. It's the only one that doesn't either break the user's CJS code or impose hand-written async boilerplate.
What this PR gets right
A bunch of details that make the integration genuinely brownfield-safe:
- Brownfield isolation via
aspire-apphost/subfolder. Whenaspire initfinds an existingpackage.json, the whole AppHost (with its ownpackage.jsoncarrying"type": "module") goes into a nested package. The user's rootpackage.json"type"is never touched. Root scripts become delegate scripts like"aspire:start": "npm --prefix aspire-apphost run aspire:start". tsconfig.apphost.jsonis isolated with"module": "NodeNext". The user'stsconfig.jsonis never overwritten — there's even a test (Scaffold_DoesNotEmitRootTsConfig_WhenOneAlreadyExists) pinning that behavior.- Scoped ESLint config (
files: ['apphost.mts']) — won't fight the user's existing lint setup. tsxis the runtime, notts-node.tsxnatively handles.mts, top-levelawait, and the.mjsimport specifiers in the SDK files.ts-nodeclassic mode is the one tool that hard-fails on.mts, and Aspire correctly avoids it.- Legacy
apphost.tsprojects continue to work.DetectionPatterns: ["apphost.mts", "apphost.ts"]plusConvertGeneratedFilesForLegacyTypeScriptAppHost()(which rewrites.mts→.tsand.mjs→.jsin generated content) means existing users see no breakage. engines.node: ^20.19.0 || ^22.13.0 || >=24matches ESLint 10's requirement and rules out Node versions that wouldn't run ESM AppHosts anyway.
Industry precedent
The pattern of "use .mts for one specific file in an otherwise-unknown project" is the dominant industry use of .mts:
- Vite docs explicitly recommend
vite.config.mtsto escape a CJS-rooted project: "renamevite.config.js/vite.config.tstovite.config.mjs/vite.config.mts." - Vitest —
vitest.config.mtsappears in 2,600+ GitHub repos. - ESLint v9 —
eslint.config.mtsappears in 1,350+ repos. - Next.js recognizes
next.config.mts. - Astro 4 adopted
astro.config.mts. - Cloudflare Workers SDK ships 71+
vitest.config.mtsfiles across packages — same exact pattern as Aspire's AppHost: a CJS-or-unknown root with a single ESM-required entrypoint.
This PR is applying the same precedent to the AppHost entrypoint rather than to a config file.
Things to consider documenting
These don't argue against .mts, but they're real brownfield tooling gotchas that would be worth a docs note:
- Root
tsconfig.jsonwith"include": ["**/*"](common in older CRA/Vite/Angular templates) will pick upapphost.mtsand fail withTS1479if the root tsconfig has"module": "CommonJS". A recommended"exclude": ["aspire-apphost", "**/.modules/**"]snippet for the user's tsconfig would prevent surprises during the user's owntscruns. ts-jest's default transform regex is^.+\.tsx?$— does not match.mts. Brownfield projects running tests throughts-jestneed either its ESM preset or^.+\.m?tsx?$plusextensionsToTreatAsEsm: ['.mts']. (Jest's ownmoduleFileExtensionsandtestMatchalready include.mts, so it's only the transform that bites.)- Webpack default
resolve.extensionswith TS enabled is[".ts", ".js", ".json", ".wasm"]— no.mts. Extensionless imports won't resolve. Explicit references work;defaultRuleshandles.mtsas ESM when encountered. - ESLint configs with
files: ["**/*.ts"]silently skip.mts. typescript-eslint's parser defaults include.mts, but explicitfiles:overrides only match what they say. The user's own lint config may need updating if they want to lint the AppHost themselves.
None of these are reasons to use .ts instead — they'd all be real problems either way, and most flip from "silently incorrect" (with .ts in a CJS project) to "loud failure during a non-Aspire build step" (with .mts). Loud failures are easier to fix.
Summary
.mtsis the Node-spec-sanctioned way to declare "this file is ESM" without writing into the user'spackage.json. Not a hack — its intended use case..tsfor the AppHost only works in projects that are already ESM. That's an assumption a brownfield-safe init can't make. CLI: TypeScript AppHost top-level await fails in brownfield repos without type:module #16124 is the documented proof.- The PR's isolation design (
aspire-apphost/nesting, isolatedtsconfig.apphost.json, scoped ESLint config,tsxruntime, legacyapphost.tscodegen path) is sound and addresses the realistic failure modes. - The biggest open item is documentation for ts-jest users and for users with broad root
tsconfig.jsonincludeglobs — not the file extension choice.
LGTM on the direction. 👍
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
f18dad0 to
c769f1a
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
❓ CLI E2E Tests unknown — 96 passed, 0 failed, 5 unknown (commit View all recordings
📹 Recordings uploaded automatically from CI run #26300715005 |
Resolves conflicts from #16984 (Use mts for TypeScript AppHosts). All generated SDK output continues to land under .aspire/modules/ (now using .mts/.mjs naming for new-style TypeScript AppHosts and preserving .ts/.js for legacy AppHosts). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR #16984 switched TypeScript AppHosts to apphost.mts. Two other deployment E2E tests still referenced apphost.ts and failed with ResourceGroupNotFound for the same reason: - TypeScriptAzureContainerAppJobDeploymentTests: writes its custom AppHost to apphost.mts instead of apphost.ts. - AksAzureKubernetesEnvironmentCertManagerTypeScriptDeploymentTests: patches apphost.mts (the file emitted by the Express/React starter) instead of the no-longer-generated apphost.ts. Supersedes #17432 and #17433. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
TypeScript AppHosts should be explicit ES modules without requiring existing applications to change their package module mode. This updates new TypeScript AppHosts to use
apphost.mtswhile keeping generated SDK output in the existing.modulesfolder.Summary
apphost.mtsimporting./.modules/aspire.mjs.mtsSDK files for new TypeScript AppHosts while preserving legacy.tsgeneration for existingapphost.tsAppHost projectsaspire initbrownfield-safe by preserving existing root files and package module settings; root JS/TS apps get a nestedaspire-apphost/package instead of having Aspire files written into the app packageExamples
package.jsoncan keep notypeor"type": "commonjs"; Aspire createsaspire-apphost/apphost.mtsand root delegate scripts.package.jsoncan keep"type": "module"; Aspire creates the same nestedaspire-apphost/apphost.mtspackage without changing root module settings.apphost.tsremains supported and continues to use.tsgenerated SDK files with.jsimports.Fixes #16124