diff --git a/eng/scripts/pack-cli-npm-package.pointer.README.md b/eng/scripts/pack-cli-npm-package.pointer.README.md index 340befe48d4..b0ab6d2d05f 100644 --- a/eng/scripts/pack-cli-npm-package.pointer.README.md +++ b/eng/scripts/pack-cli-npm-package.pointer.README.md @@ -13,52 +13,61 @@ Use an AppHost to describe how services, frontends, containers, databases, cache ## A simple app definition -The same application definition can be written in different languages. +You describe your app in a TypeScript AppHost (`apphost.mts`). The example below runs an Express API and a Vite frontend, exposes the API over HTTP, and wires the frontend to it: -__C#__ (`apphost.cs`) +```typescript +import { createBuilder } from './.aspire/modules/aspire.mjs'; -```csharp -var builder = DistributedApplication.CreateBuilder(args); +const builder = await createBuilder(); -var cache = builder.AddRedis("cache"); +// Run the Express API and expose its HTTP endpoint externally. +const app = await builder + .addNodeApp("app", "./api", "src/index.ts") + .withHttpEndpoint({ env: "PORT" }) + .withExternalHttpEndpoints(); -var api = builder.AddNodeApp("api", "./api", "src/index.ts") - .WithReference(cache) - .WaitFor(cache) - .WithHttpEndpoint(env: "PORT") - .WithExternalHttpEndpoints(); +// Run the Vite frontend after the API and inject the API URL for local proxying. +const frontend = await builder + .addViteApp("frontend", "./frontend") + .withReference(app) + .waitFor(app); -builder.AddViteApp("frontend", "./frontend") - .WithReference(api) - .WaitFor(api); +// Bundle the frontend build output into the API container for publish/deploy. +await app.publishWithContainerFiles(frontend, "./static"); -builder.Build().Run(); +await builder.build().run(); ``` -__TypeScript__ (`apphost.ts`) +Each builder call returns a promise, so `await` is used to get the resource before referencing it from another resource. `aspire run` builds and launches everything, then opens the dashboard. + +### Add backing services + +Resources like databases and caches are added the same way and connected with `withReference`. `waitFor` holds dependents until the resource is ready: ```typescript -import { createBuilder } from './.aspire/modules/aspire.js'; +import { createBuilder } from './.aspire/modules/aspire.mjs'; const builder = await createBuilder(); +const postgres = await builder.addPostgres("postgres"); +const db = await postgres.addDatabase("db"); + const cache = await builder.addRedis("cache"); -const api = await builder +await builder .addNodeApp("api", "./api", "src/index.ts") - .withReference(cache) - .waitFor(cache) .withHttpEndpoint({ env: "PORT" }) - .withExternalHttpEndpoints(); - -await builder - .addViteApp("frontend", "./frontend") - .withReference(api) - .waitFor(api); + .withExternalHttpEndpoints() + .withReference(db) + .withReference(cache) + .waitFor(db) + .waitFor(cache); await builder.build().run(); ``` +`addPostgres` and `addRedis` become available once the matching integrations are installed with `aspire add postgresql` and `aspire add redis`. + ## Install This package requires Node.js 20 or later. @@ -83,6 +92,16 @@ aspire run The native platform packages are installed through npm optional dependencies. Do not install this package with optional dependencies disabled, or the `aspire` launcher will not be able to find the native CLI binary. +## Standalone dashboard + +The Aspire dashboard shows logs, traces, and metrics for any app that exports OpenTelemetry, even without an AppHost. Start one in a single command: + +```bash +aspire dashboard run +``` + +This launches the dashboard with an OTLP endpoint your apps can point at via `OTEL_EXPORTER_OTLP_ENDPOINT`. Use `aspire dashboard run --help` to see options such as `--frontend-url`, `--otlp-grpc-url`, and `--allow-anonymous`. + ## Update ```bash diff --git a/tests/Infrastructure.Tests/Pipelines/NpmCliPackageTests.cs b/tests/Infrastructure.Tests/Pipelines/NpmCliPackageTests.cs index 3d4adcd3dc3..68643b3d032 100644 --- a/tests/Infrastructure.Tests/Pipelines/NpmCliPackageTests.cs +++ b/tests/Infrastructure.Tests/Pipelines/NpmCliPackageTests.cs @@ -186,7 +186,15 @@ public async Task PackScriptGeneratesPointerPackageMetadataMapAndReadme() Assert.Contains($"npm install -g {PackageName}", readme); Assert.Contains("The native platform packages are installed through npm optional dependencies.", readme); Assert.Contains("If you run `aspire update --self` from an npm install, the CLI points you back to this npm update command.", readme); + Assert.Contains("TypeScript AppHost (`apphost.mts`)", readme); + Assert.Contains("import { createBuilder } from './.aspire/modules/aspire.mjs';", readme); + Assert.Contains("aspire dashboard run", readme); + Assert.DoesNotContain("apphost.ts", readme); + Assert.DoesNotContain("./.aspire/modules/aspire.js", readme); Assert.DoesNotContain("__PACKAGE_NAME__", readme); + // The C# AppHost example was intentionally removed; the npm README is TypeScript-only. + Assert.DoesNotContain("apphost.cs", readme); + Assert.DoesNotContain("```csharp", readme); } [Theory]