Skip to content

Add initial server docs #6742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
changeKind: internal
packages:
- "@typespec/http-server-csharp"
- "@typespec/http-server-js"
---

Update to generate emitter docs
2 changes: 1 addition & 1 deletion packages/http-server-csharp/package.json
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@
"test:ci": "vitest run --coverage --reporter=junit --reporter=default",
"lint": "eslint . --max-warnings=0",
"lint:fix": "eslint . --fix",
"regen-docs": "echo No doc generation for alpha version",
"regen-docs": "tspd doc . --enable-experimental --output-dir ../../website/src/content/docs/docs/emitters/servers/http-server-csharp/reference --skip-js",
"emit:scenarios": "tsx eng/scripts/emit-scenarios.js --build true",
"test:scenarios": "vitest run --config ./vitest.config.scenarios.js"
},
127 changes: 127 additions & 0 deletions packages/http-server-js/.tspd/docs/footer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
## Functionality and generated code

The emitter generates a few major components:

### Router

The highest-level component that your code interacts with directly is the router implementation.
`@typespec/http-server-js` generates a static router that you can bind to an implementation of an HTTP server.

The router is generated in the `http/router.js` module within the output directory. Each service will have its own
router implementation named after the service. For example, given a service namespace named `Todo`, the router module
will export a function `createTodoRouter`. This function creates an instance of a router that dispatches methods within
the `Todo` service.

```ts
import { createTodoRouter } from "../tsp-output/@typespec/http-server-js/http/router.js";

const router = createTodoRouter(users, todoItems, attachments);
```

As arguments, the `createTodoRouter` function expects implementations of the underlying service interfaces. These
interfaces are explained further in the next section.

Once the router is created, it is bound to an instance of the HTTP server. The router's `dispatch` method implements the
Node.js event handler signature for the `request` event on a Node.js HTTP server.

```ts
const server = http.createServer();

server.on("request", router.dispatch);

server.listen(8080, () => {
console.log("Server listening on http://localhost:8080");
});
```

Alternatively, the router can be used with Express.js instead of the Node.js HTTP server directly. If the `express`
feature is enabled in the emitter options, the router will expose an `expressMiddleware` property that implements the
Express.js middleware interface.

```ts
import express from "express";

const app = express();

app.use(router.expressMiddleware);

app.listen(8080, () => {
console.log("Server listening on http://localhost:8080");
});
```

### Service interfaces

The emitter generates interfaces for each collection of service methods that exists in the service namespace.
Implementations of these interfaces are required to instantiate the router. When the router processes an HTTP request,
it will call the appropriate method on the service implementation after determining the route and method.

For example, given the following TypeSpec namespace `Users` within the `Todo` service:

```tsp
namespace Users {
@route("/users")
@post
op create(
user: User,
): WithStandardErrors<UserCreatedResponse | UserExistsResponse | InvalidUserResponse>;
}
```

The emitter will generate a corresponding interface `Users` within the module `models/all/todo/index.js` in the output
directory.

```ts
/** An interface representing the operations defined in the 'Todo.Users' namespace. */
export interface Users<Context = unknown> {
create(
ctx: Context,
user: User,
): Promise<
| UserCreatedResponse
| UserExistsResponse
| InvalidUserResponse
| Standard4XxResponse
| Standard5XxResponse
>;
}
```

An object implementing this `Users` interface must be passed to the router when it is created. The `Context` type
parameter represents the underlying protocol or framework-specific context that the service implementation may inspect.
If you need to access the HTTP request or response objects directly in the implementation of the service methods, you
must use the `HttpContext` type as the `Context` argument when implementing the service interface. Otherwise, it is safe
to use the default `unknown` argument.

```ts
import { HttpContext } from "../tsp-output/@typespec/http-server-js/helpers/router.js";
import { Users } from "../tsp-output/@typespec/http-server-js/models/all/todo/index.js";

export const users: Users<HttpContext> = {
async create(ctx, user) {
// Implementation
},
};
```

### Models

The emitter generates TypeScript interfaces that represent the model types used in the service operations. This allows
the service implementation to interact with the data structures carried over the HTTP protocol in a type-safe manner.

### Operation functions

While your code should never need to interact with these functions directly, the emitter generates a function per HTTP
operation that handles the parsing and validation of the request contents. This allows the service implementation to be
written in terms of ordinary TypeScript types and values rather than raw HTTP request and response objects. In general:

- The Node.js HTTP server or Express.js application (your code) calls the router (generated code), which determines
which service operation function (generated code) to call based on the route, method, and other HTTP metadata in the
case of shared routes.
- The operation function (generated code) deserializes the request body, query parameters, and headers into TypeScript
types, and may perform request validation.
- The operation function (generated code) calls the service implementation (your code) with the deserialized request
data.
- The service implementation (your code) returns a result or throws an error.
- The operation function (generated code) responds to the HTTP request on your behalf, converting the result or error
into HTTP response data.
1 change: 1 addition & 0 deletions packages/http-server-js/.tspd/docs/header.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:warning: **This package is highly experimental and may be subject to breaking changes and bugs.** Please expect that your code may need to be updated as this package evolves, and please report any issues you encounter.
33 changes: 18 additions & 15 deletions packages/http-server-js/README.md
Original file line number Diff line number Diff line change
@@ -2,20 +2,15 @@

:warning: **This package is highly experimental and may be subject to breaking changes and bugs.** Please expect that your code may need to be updated as this package evolves, and please report any issues you encounter.

TypeSpec HTTP server code generator for JavaScript and TypeScript.

This package generates an implementation of an HTTP server layer for a TypeSpec API. It supports binding directly to a
Node.js HTTP server or Express.js application.
TypeSpec HTTP server code generator for JavaScript

## Install

```bash
npm install @typespec/http-server-js
```

## Emitter

### Usage
## Usage

1. Via the command line

@@ -30,25 +25,33 @@ emit:
- "@typespec/http-server-js"
```

### Emitter options
The config can be extended with options as follows:

```yaml
emit:
- "@typespec/http-server-js"
options:
"@typespec/http-server-js":
option: value
```

## Emitter options

#### `express`
### `express`

**Type:** `boolean`

If set to `true`, the emitter will generate a router that exposes an Express.js middleware function in addition to the
ordinary Node.js HTTP server router.
If set to `true`, the emitter will generate a router that exposes an Express.js middleware function in addition to the ordinary Node.js HTTP server router.

If this option is not set to `true`, the `expressMiddleware` property will not be present on the generated router.

#### `omit-unreachable-types`
### `omit-unreachable-types`

**Type:** `boolean`

By default, the emitter will create interfaces that represent all models in the service namespace. If this option is set
to `true`, the emitter will only emit those types that are reachable from an HTTP operation.
By default, the emitter will create interfaces that represent all models in the service namespace. If this option is set to `true`, the emitter will only emit those types that are reachable from an HTTP operation.

#### `no-format`
### `no-format`

**Type:** `boolean`

7 changes: 5 additions & 2 deletions packages/http-server-js/package.json
Original file line number Diff line number Diff line change
@@ -23,7 +23,9 @@
"type": "module",
"main": "dist/src/index.js",
"exports": {
".": "./dist/src/index.js",
".": {
"default": "./dist/src/index.js"
},
"./testing": "./dist/src/testing/index.js"
},
"bin": {
@@ -41,7 +43,7 @@
"test:ci": "vitest run --coverage --reporter=junit --reporter=default",
"lint": "eslint . --max-warnings=0",
"lint:fix": "eslint . --fix",
"regen-docs": "echo Doc generation disabled for this package.",
"regen-docs": "tspd doc . --enable-experimental --output-dir ../../website/src/content/docs/docs/emitters/servers/http-server-js/reference --skip-js",
"test:e2e": "npm run emit:e2e && npm run run:e2e",
"emit:e2e": "node eng/scripts/emit-e2e.js",
"run:e2e": "vitest run --config ./vitest.config.e2e.js"
@@ -68,6 +70,7 @@
"@typespec/internal-build-utils": "workspace:^",
"@typespec/openapi3": "workspace:^",
"@typespec/spector": "workspace:^",
"@typespec/tspd": "workspace:^",
"@vitest/coverage-v8": "^3.0.9",
"@vitest/ui": "^3.0.9",
"fs-extra": "^11.2.0",
19 changes: 18 additions & 1 deletion packages/http-server-js/src/lib.ts
Original file line number Diff line number Diff line change
@@ -4,23 +4,40 @@
import { JSONSchemaType, createTypeSpecLibrary, paramMessage } from "@typespec/compiler";

export interface JsEmitterOptions {
/** If set to `true`, the emitter will generate a router that exposes an Express.js middleware function in addition to the ordinary Node.js HTTP server router.

If this option is not set to `true`, the `expressMiddleware` property will not be present on the generated router. */
express?: boolean;

/** By default, the emitter will create interfaces that represent all models in the service namespace. If this option is set
to `true`, the emitter will only emit those types that are reachable from an HTTP operation. */
"omit-unreachable-types": boolean;
/** If set to `true`, the emitter will not format the generated code using Prettier. */
"no-format": boolean;
}

const EmitterOptionsSchema: JSONSchemaType<JsEmitterOptions> = {
type: "object",
additionalProperties: false,
properties: {
express: { type: "boolean", nullable: true, default: false },
express: {
type: "boolean",
nullable: true,
default: false,
description:
"If set to `true`, the emitter will generate a router that exposes an Express.js middleware function in addition to the ordinary Node.js HTTP server router.\n\nIf this option is not set to `true`, the `expressMiddleware` property will not be present on the generated router.",
},
"omit-unreachable-types": {
type: "boolean",
default: false,
description:
"By default, the emitter will create interfaces that represent all models in the service namespace. If this option is set to `true`, the emitter will only emit those types that are reachable from an HTTP operation.",
},
"no-format": {
type: "boolean",
default: false,
description:
"If set to `true`, the emitter will not format the generated code using Prettier.",
},
},
required: [],
16 changes: 2 additions & 14 deletions packages/http-specs/spec-summary.md
Original file line number Diff line number Diff line change
@@ -4610,13 +4610,7 @@ Expected input body:
- Endpoint: `get /type/model/visibility`

Generate and receive output model with readonly properties.
Expected input body:

```json
{
"queryProp": 123
}
```
Expected no body with `?queryProp=123`.

Expected response body:

@@ -4631,13 +4625,7 @@ Expected response body:
- Endpoint: `head /type/model/visibility`

Generate abd send put model with write/create properties.
Expected input body:

```json
{
"queryProp": 123
}
```
Expected no body with `?queryProp=123`.

### Type_Model_Visibility_patchModel

10 changes: 9 additions & 1 deletion packages/tspd/src/ref-doc/emitters/markdown.ts
Original file line number Diff line number Diff line change
@@ -53,7 +53,10 @@ async function loadTemplate(projectRoot: string, name: string) {
export async function renderReadme(refDoc: TypeSpecRefDoc, projectRoot: string) {
const content: MarkdownDoc[] = [];
const renderer = new MarkdownRenderer(refDoc);

const headerTemplate = await loadTemplate(projectRoot, "header");
if (headerTemplate) {
content.push(headerTemplate);
}
if (refDoc.description) {
content.push(refDoc.description);
}
@@ -76,6 +79,11 @@ export async function renderReadme(refDoc: TypeSpecRefDoc, projectRoot: string)
content.push(section("Decorators", renderer.decoratorsSection(refDoc, { includeToc: true })));
}

const footerTemplate = await loadTemplate(projectRoot, "footer");
if (footerTemplate) {
content.push(footerTemplate);
}

return renderMarkdowDoc(section(refDoc.name, content));
}

9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions website/package.json
Original file line number Diff line number Diff line change
@@ -46,6 +46,8 @@
"@typespec/compiler": "workspace:^",
"@typespec/events": "workspace:^",
"@typespec/http": "workspace:^",
"@typespec/http-server-csharp": "workspace:^",
"@typespec/http-server-js": "workspace:^",
"@typespec/internal-build-utils": "workspace:^",
"@typespec/json-schema": "workspace:^",
"@typespec/openapi": "workspace:^",
21 changes: 20 additions & 1 deletion website/src/content/current-sidebar.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ function getBadgeForLibraryStability(stability: LibraryStability | undefined): B
case "beta":
return { text: "beta", variant: "caution" };
case "alpha":
return { text: "beta", variant: "caution" };
return { text: "alpha", variant: "caution" };
case "stable":
default:
return undefined;
@@ -208,6 +208,25 @@ const sidebar: SidebarItem[] = [
),
],
},
{
label: "Servers",
items: [
createLibraryReferenceStructure(
"emitters/servers/http-server-csharp",
"ASP.Net",
false,
["emitters/servers/http-server-csharp/project"],
"alpha",
),
createLibraryReferenceStructure(
"emitters/servers/http-server-js",
"JavaScript",
false,
["emitters/servers/http-server-js/project"],
"alpha",
),
],
},
],
},
{
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: About Generated Projects
---

**This package is highly experimental and may be subject to breaking changes and bugs.** Please expect that your code may need to be updated as this package evolves, and please report any issues you encounter.

## Layout

The code layout inside the 'generated' folder is as follows:

- **generated**

- **controllers**: A set of ASP.Net core MVC controllers representing the operations in the spec, one for each interface or namespace with operations
- **lib**: A set of library files used in implementing generated models and controllers
- **models**: A set of models, each serving one of two distinct purposes:
- Request/Response Models: Represent the data used in requests and responses.
- Exception Models: Represent errors. These models inherit from `HttpServiceException` and are designed to encapsulate error details, making them suitable for throwing and handling exceptions.
- **operations**: A set of interfaces called by the controllers, that should be implemented with the business logic for each operation.

You should recompile whenever you make changes in your TypeSpec and these files will be replaced inline to reflect the spec changes, without changing any of your hand-written implementation in the project.

## Scaffolding

If you use the scaffolding cli (hscs-scaffold) or use the `--emit-mocks "mocks-and-project-files"` option on compilation, a fully-functional .Net 9 project will be created with mock implementations of your business
logic, ready to compile and run.

The following additional files will be generated. It is expected that you will edit or replace these
files as you implement your service, so you should only regenerate them when needed.
To protect from inadvertently changing any edits you may have made to these files,
these files will be overwritten by the emitter unless you specify the `--overwrite` option.

- **ServiceProject.csproj**: The project file
- **Program.cs**: Entry point that sets up the app
- **appSettings.Development.json**: Configuration settings for the development environment
- **appSettings.json**: Configuration settings for the production environment
- **Properties**
- **launchSettings.json**: Launch configurations for the service (including local ports)
- **mocks**: Simple implementations of business logic interfaces that return simple responses.
this allows testing your service out before writing any implementation code.

- **MockRegistration.cs**: Called from the Program.cs startup, registers each of the business
logic implementations in the dependency injection container.
- **IInitializer.cs**: Interface used in the mocks to create responses.
- **Initializer.cs**: Implementation of the interface to create mock responses.

### Generating a Project and Mock Implementations using `tsp compile`

If you downloaded the `tsp` standalone component and you don't have `node` and `npm` installed, you will not be able to use the `hscs-scaffold` command to create an ASP.Net project. Instead, you can use compiler options, for example, the following command will create a new project using the TypeSpec in the current directory, enabling SwaggerUI, and overwriting any existing mocks or project files:

```bash
compile > tsp . --emit @typespec/http-server-csharp --emit @typespec/openapi3 --option @typespec/http-server-csharp.emit-mocks=emit-mocks-and-project-files --option @typespec/http-server-csharp.use-swaggerui=true --option @typespec/http-server-csharp.overwrite=true
```

Once you have customized the project, you can generate new mocks for any new APIs while leaving existing implementations unchanged using:

```bash
compile > tsp . --emit @typespec/http-server-csharp --option @typespec/http-server-csharp.emit-mocks=mocks-only
```

## SwaggerUI

If you include the `@typespec/openapi3` emitter in your typespec project, you can include a
SwaggerUI endpoint in the generated service using the `--use-swaggerui` option. This endpoint
provides a visual representation of operations and provides a web GUI client connected to the service that you can use right away to try out service operations.

## How Components Work Together

### Controllers

The generated controllers automatically listen at the routes you specified in TypeSpec. Controllers perform validation of input requests, call your implementation of business logic interfaces to perform the operation, and return the appropriate Http response.

### Business Logic Interfaces

You must implement business loginc interfaces to perform the work of each operation. There is one
business logic interface for each `interface` type in your spec, or for each namespace that contain operations. Business logic can assume that input types meet the constraints specified in TypeSpec and are responsible for returning the response type for the operation.

You can use the `--emit-mocks` option to emit mock implementations of your business logic, these mocks demonstrate a simple implementation that returns responses that match the response type in TypeSpec. They also show how to use `IHttpContextAccessor` to access additional details of the Http request and response.

### Discovery using the ASP.Net Core Dependency Injection Container

The Controllers find your business logic implementation through the ASP.Net dependency injection container. At server start, you register each of your implementations with the dependency injection container and they will automatically be instantiated and used by the controllers.

If you use the `--emit-mocks` option, sample code registering mock implementations is emitted to `mocks/MockRegistration.cs`.

### Models

Model classes represent the data passed in Http requests and response and the data that passes from the front end controllers to your business logic.

Models are partial, so you can add additional members for internal usage as needed by putting a partial class definition with additional members outside the `generated` folder in your project.

### Next Steps

After successful generation, you should:

- Use the SwaggerUI endpoint to test out the running service
- Implement the business logic interfaces for your operations
- Update MockRegistration.cs, or register each of your interfaces as part of application startup
- Update configuration to suit your needs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: "Emitter usage"
---

## Usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/http-server-csharp
```

2. Via the config

```yaml
emit:
- "@typespec/http-server-csharp"
```
The config can be extended with options as follows:
```yaml
emit:
- "@typespec/http-server-csharp"
options:
"@typespec/http-server-csharp":
option: value
```
## Emitter options
### `skip-format`

**Type:** `boolean`

Skips formatting of generated C# Types. By default, C# files are formatted using 'dotnet format'.

### `output-type`

**Type:** `"models" | "all"`

Chooses which service artifacts to emit. choices include 'models' or 'all' artifacts.

### `emit-mocks`

**Type:** `"mocks-and-project-files" | "mocks-only" | "none"`

Emits mock implementations of business logic, setup code, and project files, enabling the service to respond to requests before a real implementation is provided

### `use-swaggerui`

**Type:** `boolean`

Configure a Swagger UI endpoint in the development configuration

### `openapi-path`

**Type:** `string`

Use openapi at the given path for generating SwaggerUI endpoints. By default, this will be 'openapi/openapi.yaml' if the 'use-swaggerui' option is enabled.

### `overwrite`

**Type:** `boolean`

When generating mock and project files, overwrite any existing files with the same name.

### `project-name`

**Type:** `string`

The name of the generated project.

### `http-port`

**Type:** `number`

The service http port when hosting the project locally.

### `https-port`

**Type:** `number`

The service https port when hosting the project locally.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

import { Tabs, TabItem } from '@astrojs/starlight/components';

TypeSpec service code generator for c-sharp

## Install

<Tabs>
<TabItem label="In a spec" default>

```bash
npm install @typespec/http-server-csharp
```

</TabItem>
<TabItem label="In a library" default>

```bash
npm install --save-peer @typespec/http-server-csharp
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: About Generated Projects
---

**This package is highly experimental and may be subject to breaking changes and bugs.** Please expect that your code may need to be updated as this package evolves, and please report any issues you encounter.

## Functionality and generated code

The emitter generates a few major components:

### Router

The highest-level component that your code interacts with directly is the router implementation.
`@typespec/http-server-js` generates a static router that you can bind to an implementation of an HTTP server.

The router is generated in the `http/router.js` module within the output directory. Each service will have its own
router implementation named after the service. For example, given a service namespace named `Todo`, the router module
will export a function `createTodoRouter`. This function creates an instance of a router that dispatches methods within
the `Todo` service.

```ts
import { createTodoRouter } from "../tsp-output/@typespec/http-server-js/http/router.js";

const router = createTodoRouter(users, todoItems, attachments);
```

As arguments, the `createTodoRouter` function expects implementations of the underlying service interfaces. These
interfaces are explained further in the next section.

Once the router is created, it is bound to an instance of the HTTP server. The router's `dispatch` method implements the
Node.js event handler signature for the `request` event on a Node.js HTTP server.

```ts
const server = http.createServer();

server.on("request", router.dispatch);

server.listen(8080, () => {
console.log("Server listening on http://localhost:8080");
});
```

Alternatively, the router can be used with Express.js instead of the Node.js HTTP server directly. If the `express`
feature is enabled in the emitter options, the router will expose an `expressMiddleware` property that implements the
Express.js middleware interface.

```ts
import express from "express";

const app = express();

app.use(router.expressMiddleware);

app.listen(8080, () => {
console.log("Server listening on http://localhost:8080");
});
```

### Service interfaces

The emitter generates interfaces for each collection of service methods that exists in the service namespace.
Implementations of these interfaces are required to instantiate the router. When the router processes an HTTP request,
it will call the appropriate method on the service implementation after determining the route and method.

For example, given the following TypeSpec namespace `Users` within the `Todo` service:

```tsp
namespace Users {
@route("/users")
@post
op create(
user: User,
): WithStandardErrors<UserCreatedResponse | UserExistsResponse | InvalidUserResponse>;
}
```

The emitter will generate a corresponding interface `Users` within the module `models/all/todo/index.js` in the output
directory.

```ts
/** An interface representing the operations defined in the 'Todo.Users' namespace. */
export interface Users<Context = unknown> {
create(
ctx: Context,
user: User,
): Promise<
| UserCreatedResponse
| UserExistsResponse
| InvalidUserResponse
| Standard4XxResponse
| Standard5XxResponse
>;
}
```

An object implementing this `Users` interface must be passed to the router when it is created. The `Context` type
parameter represents the underlying protocol or framework-specific context that the service implementation may inspect.
If you need to access the HTTP request or response objects directly in the implementation of the service methods, you
must use the `HttpContext` type as the `Context` argument when implementing the service interface. Otherwise, it is safe
to use the default `unknown` argument.

```ts
import { HttpContext } from "../tsp-output/@typespec/http-server-js/helpers/router.js";
import { Users } from "../tsp-output/@typespec/http-server-js/models/all/todo/index.js";

export const users: Users<HttpContext> = {
async create(ctx, user) {
// Implementation
},
};
```

### Models

The emitter generates TypeScript interfaces that represent the model types used in the service operations. This allows
the service implementation to interact with the data structures carried over the HTTP protocol in a type-safe manner.

### Operation functions

While your code should never need to interact with these functions directly, the emitter generates a function per HTTP
operation that handles the parsing and validation of the request contents. This allows the service implementation to be
written in terms of ordinary TypeScript types and values rather than raw HTTP request and response objects. In general:

- The Node.js HTTP server or Express.js application (your code) calls the router (generated code), which determines
which service operation function (generated code) to call based on the route, method, and other HTTP metadata in the
case of shared routes.
- The operation function (generated code) deserializes the request body, query parameters, and headers into TypeScript
types, and may perform request validation.
- The operation function (generated code) calls the service implementation (your code) with the deserialized request
data.
- The service implementation (your code) returns a result or throws an error.
- The operation function (generated code) responds to the HTTP request on your behalf, converting the result or error
into HTTP response data.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: "Emitter usage"
---

## Usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/http-server-js
```

2. Via the config

```yaml
emit:
- "@typespec/http-server-js"
```
The config can be extended with options as follows:
```yaml
emit:
- "@typespec/http-server-js"
options:
"@typespec/http-server-js":
option: value
```
## Emitter options
### `express`

**Type:** `boolean`

If set to `true`, the emitter will generate a router that exposes an Express.js middleware function in addition to the ordinary Node.js HTTP server router.

If this option is not set to `true`, the `expressMiddleware` property will not be present on the generated router.

### `omit-unreachable-types`

**Type:** `boolean`

By default, the emitter will create interfaces that represent all models in the service namespace. If this option is set to `true`, the emitter will only emit those types that are reachable from an HTTP operation.

### `no-format`

**Type:** `boolean`

If set to `true`, the emitter will not format the generated code using Prettier.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

import { Tabs, TabItem } from '@astrojs/starlight/components';

TypeSpec HTTP server code generator for JavaScript

## Install

<Tabs>
<TabItem label="In a spec" default>

```bash
npm install @typespec/http-server-js
```

</TabItem>
<TabItem label="In a library" default>

```bash
npm install --save-peer @typespec/http-server-js
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)