Skip to content

Commit 5da2cf2

Browse files
Fix TypeScript documentation gaps (#1204)
* Fix TypeScript documentation gaps Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Avoid twoslash rendering for new TypeScript samples The additional TypeScript examples still render as TypeScript code blocks, but not through twoslash. This avoids the frontend production build exceeding the default Node heap while preserving existing twoslash coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address certificate twoslash review Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use refExpr in certificate TypeScript samples Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use secret parameter for Seq admin password Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d210b77 commit 5da2cf2

26 files changed

Lines changed: 1030 additions & 164 deletions

src/frontend/src/content/docs/app-host/certificate-configuration.mdx

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,27 @@ builder.Build().Run();
185185
```
186186
</TabItem>
187187
<TabItem id='typescript' label='TypeScript'>
188-
<Aside type="note">
189-
This API is not yet available in TypeScript AppHosts.
190-
</Aside>
188+
```typescript title="apphost.mts" twoslash
189+
import { createBuilder, refExpr } from './.aspire/modules/aspire.mjs';
190+
191+
const builder = await createBuilder();
192+
193+
const api = await builder.addContainer("api", {
194+
image: "my-api",
195+
tag: "latest",
196+
});
197+
198+
api.createExecutionConfiguration()
199+
.withArgumentsConfig()
200+
.withEnvironmentVariablesConfig()
201+
.withHttpsCertificateConfig(async () => ({
202+
certificatePath: refExpr`/certs/tls.crt`,
203+
keyPath: refExpr`/certs/tls.key`,
204+
pfxPath: refExpr`/certs/tls.pfx`,
205+
}));
206+
207+
await builder.build().run();
208+
```
191209
</TabItem>
192210
</Tabs>
193211

@@ -272,9 +290,28 @@ builder.Build().Run();
272290
```
273291
</TabItem>
274292
<TabItem id='typescript' label='TypeScript'>
275-
<Aside type="note">
276-
This API is not yet available in TypeScript AppHosts.
277-
</Aside>
293+
```typescript title="apphost.mts" twoslash
294+
import { createBuilder, refExpr } from './.aspire/modules/aspire.mjs';
295+
296+
const builder = await createBuilder();
297+
298+
const api = await builder.addContainer("api", {
299+
image: "myimage",
300+
tag: "latest",
301+
});
302+
303+
api.createExecutionConfiguration()
304+
.withArgumentsConfig()
305+
.withEnvironmentVariablesConfig()
306+
.withCertificateTrustConfig(async () => ({
307+
certificateBundlePath: refExpr`/certs/ca-bundle.crt`,
308+
certificateDirectoriesPath: refExpr`/certs`,
309+
rootCertificatesPath: "/etc/ssl/certs",
310+
isContainer: true,
311+
}));
312+
313+
await builder.build().run();
314+
```
278315
</TabItem>
279316
</Tabs>
280317

src/frontend/src/content/docs/app-host/container-files.mdx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,19 @@ builder.Build().Run();
9090
```
9191
</TabItem>
9292
<TabItem id='typescript' label='TypeScript'>
93-
:::note
94-
The `withContainerFiles` API is not yet available in the TypeScript AppHost SDK.
95-
:::
93+
```typescript title="apphost.mts"
94+
import { createBuilder } from './.aspire/modules/aspire.mjs';
95+
96+
const builder = await createBuilder();
97+
98+
const frontend = await builder.addViteApp("frontend", "../frontend");
99+
await frontend.withContainerFilesSource("/app/dist");
100+
101+
const api = await builder.addProject("api", "../Api/Api.csproj");
102+
await api.publishWithContainerFiles(frontend, "./wwwroot");
103+
104+
await builder.build().run();
105+
```
96106
</TabItem>
97107
</Tabs>
98108

src/frontend/src/content/docs/app-host/withdockerfile.mdx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,22 @@ builder.Build().Run();
280280
</TabItem>
281281
<TabItem id='typescript' label='TypeScript'>
282282

283-
TypeScript AppHost support for Dockerfile factory APIs isn't available because `DockerfileFactoryContext` exposes .NET runtime types that aren't part of the polyglot SDK surface. Use the [Dockerfile builder APIs](#generate-a-dockerfile-programmatically) for TypeScript AppHosts.
283+
```typescript title="apphost.mts"
284+
import { createBuilder } from './.aspire/modules/aspire.mjs';
285+
286+
const builder = await createBuilder();
287+
288+
const container = await builder.addDockerfileFactory("myapp", "../myapp", async () => `
289+
FROM node:22-alpine
290+
WORKDIR /app
291+
COPY . .
292+
RUN npm ci
293+
EXPOSE 3000
294+
CMD ["node", "server.js"]
295+
`);
296+
297+
await builder.build().run();
298+
```
284299

285300
</TabItem>
286301
</Tabs>
@@ -309,7 +324,20 @@ builder.Build().Run();
309324
</TabItem>
310325
<TabItem id='typescript' label='TypeScript'>
311326

312-
TypeScript AppHost support for Dockerfile factory APIs isn't available because `DockerfileFactoryContext` exposes .NET runtime types that aren't part of the polyglot SDK surface. Use the [Dockerfile builder APIs](#generate-a-dockerfile-programmatically) for TypeScript AppHosts.
327+
```typescript title="apphost.mts"
328+
import { createBuilder } from './.aspire/modules/aspire.mjs';
329+
330+
const builder = await createBuilder();
331+
332+
await builder.addContainer("myapp", { image: "placeholder", tag: "latest" })
333+
.withDockerfileFactory("../myapp", async () => `
334+
FROM nginx:alpine
335+
COPY dist/ /usr/share/nginx/html
336+
EXPOSE 80
337+
`);
338+
339+
await builder.build().run();
340+
```
313341

314342
</TabItem>
315343
</Tabs>

src/frontend/src/content/docs/deployment/docker-compose.mdx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,22 @@ var api = builder.AddProject<Projects.Api>("api")
583583
```
584584
</TabItem>
585585
<TabItem id='typescript' label='TypeScript'>
586-
:::note
587-
The `WithImagePushOptions` API is not yet available in the TypeScript AppHost SDK.
588-
:::
586+
```typescript title="apphost.mts"
587+
import { createBuilder } from './.aspire/modules/aspire.mjs';
588+
589+
const builder = await createBuilder();
590+
591+
const api = await builder.addProject('api', '../Api/Api.csproj');
592+
await api
593+
.publishAsDockerComposeService(async (resource, service) => {
594+
await service.name.set('api');
595+
})
596+
.withImagePushOptions(async (context) => {
597+
const imageName = context.resource.getResourceName().toLowerCase();
598+
context.options.setRemoteImageName(`myorg/${imageName}`);
599+
context.options.setRemoteImageTag('latest');
600+
});
601+
```
589602
</TabItem>
590603
</Tabs>
591604

src/frontend/src/content/docs/deployment/pipelines.mdx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,29 @@ var api = builder.AddProject<Api>("api").WithReference(database);
297297
````
298298
</TabItem>
299299
<TabItem id='typescript' label='TypeScript'>
300-
:::note
301-
The `builder.pipeline` API is not yet available in the TypeScript AppHost SDK, so this custom pipeline example is currently C#-only.
302-
:::
300+
```typescript title="apphost.mts"
301+
import { createBuilder } from './.aspire/modules/aspire.mjs';
302+
303+
const builder = await createBuilder();
304+
305+
// Add custom deployment validation
306+
builder.pipeline.addStep("validate-deployment", async (context) => {
307+
// Custom validation logic
308+
await validateApiHealth(context);
309+
await validateDatabaseConnection(context);
310+
}, { requiredBy: ["deploy"] });
311+
312+
// Define resources
313+
const database = await builder.addPostgres("myapp-db");
314+
const api = await builder.addProject("api", "../Api/Api.csproj");
315+
await api.withReference(database);
316+
317+
async function validateApiHealth(_context: unknown) {
318+
}
319+
320+
async function validateDatabaseConnection(_context: unknown) {
321+
}
322+
```
303323
</TabItem>
304324
</Tabs>
305325

src/frontend/src/content/docs/integrations/ai/ollama/ollama-host.mdx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,18 @@ ollama.AddModel("llama3");
390390
```
391391
</TabItem>
392392
<TabItem id="typescript" label="TypeScript">
393+
```typescript title="TypeScript — apphost.mts"
394+
import { createBuilder } from "./.aspire/modules/aspire.mjs";
393395

394-
<Aside type="note">
395-
TypeScript AppHost support for `WithOpenWebUI` is not available in the current Community Toolkit TypeScript bindings. Use the C# AppHost to enable Open WebUI.
396-
</Aside>
396+
const builder = await createBuilder();
397+
398+
const ollama = await builder.addOllama("ollama");
399+
await ollama.withOpenWebUI();
400+
401+
await ollama.addModel("llama3");
402+
403+
// After adding all resources, run the app...
404+
```
397405

398406
</TabItem>
399407
</Tabs>
@@ -408,4 +416,3 @@ The Ollama hosting integration automatically adds health checks for both the Oll
408416

409417
- **Server health check.** Verifies that the Ollama server is running and that a connection can be established to it.
410418
- **Model health check.** Verifies that a model has been downloaded and is available. The model resource is marked as unhealthy until the download completes.
411-

src/frontend/src/content/docs/integrations/caching/redis-extensions.mdx

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Extend the functionality of your Redis hosting with community-built
44
next: false
55
---
66

7-
import { Badge, Tabs, TabItem, Aside } from '@astrojs/starlight/components';
7+
import { Badge, Tabs, TabItem } from '@astrojs/starlight/components';
88
import InstallPackage from '@components/InstallPackage.astro';
99
import { Image } from 'astro:assets';
1010
import redisIcon from '@assets/icons/redis-icon.png';
@@ -38,9 +38,19 @@ To get started with the Aspire Community Toolkit Redis hosting extensions, insta
3838
</TabItem>
3939
<TabItem id='typescript' label='TypeScript'>
4040

41-
<Aside type="note">
42-
The Community Toolkit Redis extensions package (`CommunityToolkit.Aspire.Hosting.Redis.Extensions`) is a .NET-only package. The extension APIs such as `WithDbGate` are not available in TypeScript AppHosts. Use the official [Redis integration](/integrations/caching/redis/redis-get-started/) to add Redis to a TypeScript AppHost.
43-
</Aside>
41+
```bash title="Terminal"
42+
aspire add CommunityToolkit.Aspire.Hosting.Redis.Extensions
43+
```
44+
45+
This updates your `aspire.config.json` with the Redis extensions package:
46+
47+
```json title="aspire.config.json" ins={3}
48+
{
49+
"packages": {
50+
"CommunityToolkit.Aspire.Hosting.Redis.Extensions": "*"
51+
}
52+
}
53+
```
4454

4555
</TabItem>
4656
</Tabs>
@@ -69,9 +79,21 @@ builder.AddProject<Projects.ExampleProject>()
6979
</TabItem>
7080
<TabItem id='typescript' label='TypeScript'>
7181

72-
<Aside type="note">
73-
The `WithDbGate` extension is not available in TypeScript AppHosts. DbGate management UI configuration is a C#-only feature.
74-
</Aside>
82+
```typescript title="TypeScript — apphost.mts"
83+
import { createBuilder } from "./.aspire/modules/aspire.mjs";
84+
85+
const builder = await createBuilder();
86+
87+
const redis = await builder.addRedis("redis");
88+
await redis.withDbGate();
89+
90+
const exampleProject = await builder.addProject(
91+
"example-project",
92+
"../ExampleProject/ExampleProject.csproj");
93+
await exampleProject.withReference(redis);
94+
95+
// After adding all resources, run the app...
96+
```
7597

7698
</TabItem>
7799
</Tabs>

src/frontend/src/content/docs/integrations/cloud/azure/azure-data-explorer.mdx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,30 @@ builder.AddProject<Projects.ExampleProject>()
228228
```
229229
</TabItem>
230230
<TabItem id="typescript" label="TypeScript">
231-
The TypeScript AppHost doesn't currently expose `withCreationScript` on the database resource. To initialise the emulator database schema from a TypeScript AppHost, apply schema through your application on startup instead.
231+
```typescript title="apphost.mts"
232+
import { createBuilder } from './.aspire/modules/aspire.mjs';
233+
234+
const builder = await createBuilder();
235+
236+
const kusto = await builder.addAzureKustoCluster("kusto")
237+
.runAsEmulator();
238+
239+
const database = await kusto.addReadWriteDatabase("analytics")
240+
.withCreationScript(`
241+
.create table Events (
242+
Timestamp: datetime,
243+
EventType: string,
244+
Message: string
245+
)
246+
`);
247+
248+
const exampleProject = await builder.addProject("example", "../ExampleProject/ExampleProject.csproj");
249+
await exampleProject
250+
.withReference(database)
251+
.waitFor(database);
252+
253+
// After adding all resources, run the app...
254+
```
232255
</TabItem>
233256
</Tabs>
234257

src/frontend/src/content/docs/integrations/cloud/azure/container-app-jobs.mdx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ builder.AddProject<Projects.DataProcessor>("data-processor")
4242
```
4343
</TabItem>
4444
<TabItem id="typescript" label="TypeScript">
45-
<Aside type="note">
46-
The `PublishAsAzureContainerAppJob` and `PublishAsScheduledAzureContainerAppJob` APIs are not yet available in the TypeScript AppHost. To deploy a TypeScript-based worker as an Azure Container App Job, configure the job via the Azure portal or Bicep outside of the AppHost.
47-
</Aside>
45+
```typescript title="apphost.mts"
46+
import { createBuilder } from './.aspire/modules/aspire.mjs';
47+
48+
const builder = await createBuilder();
49+
50+
const dataProcessor = await builder.addProject("data-processor", "../DataProcessor/DataProcessor.csproj");
51+
await dataProcessor.publishAsScheduledAzureContainerAppJob("0 0 * * *"); // Every day at midnight
52+
```
4853
</TabItem>
4954
</Tabs>
5055

src/frontend/src/content/docs/integrations/compute/docker.mdx

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,22 @@ var api = builder.AddProject<Projects.Api>("api")
637637
```
638638
</TabItem>
639639
<TabItem id='typescript' label='TypeScript'>
640-
:::note
641-
The `WithImagePushOptions` API is not yet available in the TypeScript AppHost SDK. Use `withRemoteImageName` and `withRemoteImageTag` for static image naming and tagging.
642-
:::
640+
```typescript title="apphost.mts"
641+
import { createBuilder } from './.aspire/modules/aspire.mjs';
642+
643+
const builder = await createBuilder();
644+
645+
const api = await builder.addProject("api", "../Api/Api.csproj");
646+
await api
647+
.publishAsDockerComposeService(async (resource, service) => {
648+
await service.name.set("api");
649+
})
650+
.withImagePushOptions(async (context) => {
651+
const imageName = context.resource.getResourceName().toLowerCase();
652+
context.options.setRemoteImageName(`myorg/${imageName}`);
653+
context.options.setRemoteImageTag("latest");
654+
});
655+
```
643656
</TabItem>
644657
</Tabs>
645658

@@ -666,9 +679,29 @@ var api = builder.AddProject<Projects.Api>("api")
666679
```
667680
</TabItem>
668681
<TabItem id='typescript' label='TypeScript'>
669-
:::note
670-
The asynchronous `WithImagePushOptions` callback overload is not yet available in the TypeScript AppHost SDK.
671-
:::
682+
```typescript title="apphost.mts"
683+
import { createBuilder } from './.aspire/modules/aspire.mjs';
684+
685+
const builder = await createBuilder();
686+
687+
const api = await builder.addProject("api", "../Api/Api.csproj");
688+
await api
689+
.publishAsDockerComposeService(async (resource, service) => {
690+
await service.name.set("api");
691+
})
692+
.withImagePushOptions(async (context) => {
693+
const config = await loadImageConfiguration();
694+
context.options.setRemoteImageName(config.imageName);
695+
context.options.setRemoteImageTag(config.imageTag);
696+
});
697+
698+
async function loadImageConfiguration() {
699+
return {
700+
imageName: "myorg/api",
701+
imageTag: "latest",
702+
};
703+
}
704+
```
672705
</TabItem>
673706
</Tabs>
674707

0 commit comments

Comments
 (0)