# Technical Documentation: microsoft/typespec

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/microsoft/typespec)

### Overview (`README.md`)

# TypeSpec

[Official Docs](https://typespec.io/) | [Try TypeSpec Online](https://aka.ms/trytypespec) | [Getting Started](https://typespec.io/docs) | [Language Overview](https://typespec.io/docs/language-basics/overview)

TypeSpec is a language for defining cloud service APIs and shapes. TypeSpec is a highly extensible language with primitives that can describe API shapes common among REST, OpenAPI, gRPC, and other protocols.

TypeSpec is excellent for generating many different API description formats, client and service code, documentation, and other assets while keeping your TypeSpec definition as a single source of truth.

Using TypeSpec, you can create reusable patterns for all aspects of an API and package those reusable patterns into libraries. These patterns establish "guardrails" for API designers and make it easier to follow best practices than to deviate from them. TypeSpec also has a rich linter framework with the ability to flag anti-patterns as well as an emitter framework that lets you control the output to ensure it follows the patterns you want.

TypeSpec is a Microsoft-built, community-supported project. Your ideas, feedbacks, and code make all the difference and we deeply appreciate the support from the community.

## [Installation](https://typespec.io/docs)

```
npm install @typespec/compiler
```

#### Tools

The [TypeSpec VS Code extension](https://marketplace.visualstudio.com/items?itemName=typespec.typespec-vscode) can be installed from the VS Code [marketplace](https://marketplace.visualstudio.com/items?itemName=typespec.typespec-vscode) or directly on the command line:

```
tsp code install
```

The [TypeSpec VS Extension](https://marketplace.visualstudio.com/items?itemName=typespec.typespecvs) can be installed from the [VS Marketplace](https://marketplace.visualstudio.com/items?itemName=typespec.typespecvs) or directly on the command line:

```
tsp vs install
```

## [Usage](https://typespec.io/docs#create-first-typespec-project)

### TypeSpec to OpenAPI 3.0 Example

This example uses the `@typespec/http`, `@typespec/rest`, and `@typespec/openapi3` libraries to define a basic REST service and generate an OpenAPI 3.0 document from it.

Run the following command and select "Generic REST API":

```
tsp init
```

Hit enter a few times to confirm the defaults.

Copy the contents below into your **main.tsp**:

```typespec
import "@typespec/http";
import "@typespec/rest";
import "@typespec/openapi3";

using Http;
using Rest;

/** This is a pet store service. */
@service(#{ title: "Pet Store Service" })
@server("https://example.com", "The service endpoint")
namespace PetStore;

@route("/pets")
interface Pets {
  list(): Pet[];
}

model Pet {
  @minLength(100)
  name: string;

  @minValue(0)
  @maxValue(100)
  age: int32;

  kind: "dog" | "cat" | "fish";
}
```

Install the dependencies of main.tsp:

```
tsp install
```

Compile it to OpenAPI 3.0:

```
tsp compile main.tsp --emit @typespec/openapi3
```

You can find the emitted OpenAPI output in `./tsp-output/openapi.json`.

## Advanced Scenarios

### Installing nightly version

On every commit to the main branch, packages with changes are automatically published to npm with the `@next` tag.
The [packages](#packages) section shows which version corresponds to the `next` tag for each package.

To use a `nightly` version of the packages, go over each one of the packages in the `package.json` file and update it to either the latest published `@next` version or `@latest`, whichever is the newest. You can also use the tag `latest` or `next` instead of an explicit version.

After updating the package.json file you can run `npm update --force`. Force is required as there might be some incompatible version requirement.

Example

```json5
// Stable setup
"dependencies": {
  "@typespec/compiler": "~0.30.0",
  "@typespec/http": "~0.14.0",
  "@typespec/rest": "~0.14.0",
  "@typespec/openapi": "~0.9.0",
}

// Consume next version
// In this example: compiler and openapi have changes but rest library has none
"dependencies": {
  "@typespec/compiler": "~0.31.0-dev.5",
  "@typespec/http": "~0.14.0",
  "@typespec/rest": "~0.14.0", // No changes to @typespec/rest library so need to stay the latest.
  "@typespec/openapi": "~0.10.0-dev.2",
}
```

## Packages

| Name                                               | Changelog                        | Latest                                                                                                                                   | Next                                                                      |
| -------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Core functionality                                 |                                  |                                                                                                                                          |                                                                           |
| [@typespec/compiler][compiler_src]                 | [Changelog][compiler_chg]        | [](https://www.npmjs.com/package/@typespec/compiler)                                 |                  |
| TypeSpec Libraries                                 |                                  |                                                                                                                                          |                                                                           |
| [@typespec/http][http_src]                         | [Changelog][http_chg]            | [](https://www.npmjs.com/package/@typespec/http)                                         |                      |
| [@typespec/rest][rest_src]                         | [Changelog][rest_chg]            | [](https://www.npmjs.com/package/@typespec/rest)                                         |                      |
| [@typespec/openapi][openapi_src]                   | [Changelog][openapi_chg]         | [](https://www.npmjs.com/package/@typespec/openapi)                                   |                   |
| [@typespec/openapi3][openapi3_src]                 | [Changelog][openapi3_chg]        | [](https://www.npmjs.com/package/@typespec/openapi3)                                 |                  |
| [@typespec/versioning][versioning_src]             | [Changelog][versioning_chg]      | [](https://www.npmjs.com/package/@typespec/versioning)                             |                |
| TypeSpec Tools                                     |                                  |                                                                                                                                          |                                                                           |
| [@typespec/prettier-plugin-typespec][prettier_src] | [Changelog][prettier_chg]        | [](https://www.npmjs.com/package/@typespec/prettier-plugin-typespec) |  |
| [typespec-vs][typespec-vs_src]                     | [Changelog][typespec-vs_chg]     | [](https://www.npmjs.com/package/typespec-vs)                                               |                         |
| [typespec-vscode][typespec-vscode_src]             | [Changelog][typespec-vscode_chg] | [](https://www.npmjs.com/package/typespec-vscode)                                       |                     |
| [tmlanguage-generator][tmlanguage_src]             | [Changelog][tmlanguage_chg]      | [](https://www.npmjs.com/package/tmlanguage-generator)                             |                |

[compiler_src]: packages/compiler
[compiler_chg]: packages/compiler/CHANGELOG.md
[http_src]: packages/http
[http_chg]: packages/http/CHANGELOG.md
[rest_src]: packages/rest
[rest_chg]: packages/rest/CHANGELOG.md
[openapi_src]: packages/openapi
[openapi_chg]: packages/openapi/CHANGELOG.md
[openapi3_src]: packages/openapi3
[openapi3_chg]: packages/openapi3/CHANGELOG.md
[versioning_src]: packages/versioning
[versioning_chg]: packages/versioning/CHANGELOG.md
[prettier_src]: packages/prettier-plugin-typespec
[prettier_chg]: packages/prettier-plugin-typespec/CHANGELOG.md
[typespec-vs_src]: packages/typespec-vs
[typespec-vs_chg]: packages/typespec-vs/CHANGELOG.md
[typespec-vscode_src]: packages/typespec-vscode
[typespec-vscode_chg]: packages/typespec-vscode/CHANGELOG.md
[tmlanguage_src]: packages/tmlanguage-generator
[tmlanguage_chg]: packages/tmlanguage-generator/CHANGELOG.md

`@next` version of the package are the latest versions available on the `main` branch.

---

### Overview (`docker/readme.md`)

# Use TypeSpec via Docker

Image: `azsdkengsys.azurecr.io/typespec`

Tags:

- Lastest from master: `alpine`, `latest`

## Usage

```bash
docker run \
  -v "${pwd}:/wd" --workdir="/wd" \
  -t azsdkengsys.azurecr.io/typespec
# ... TypeSpec args ...
```

**For usage in PowerShell replace `\` with `` ` ``**

### Install dependencies

```bash
docker run -v "${pwd}:/wd" --workdir="/wd" -t azsdkengsys.azurecr.io/typespec install
```

### Compile

```bash
docker run -v "${pwd}:/wd" --workdir="/wd" -t azsdkengsys.azurecr.io/typespec compile .
```

### Init a new project

```bash
docker run -v "${pwd}:/wd" --workdir="/wd" -t azsdkengsys.azurecr.io/typespec init
```

---

### Overview (`docs/readme.md`)

## Docs moved

Docs have moved into the website folder [../website/src/content/docs/docs](../website/src/content/docs/docs)

### For reference

This is an unfortunate current limitation of astro starlight. If things change in the future this is the current limitations:

- content folder MUST be under the astro website package(default src/content)
- astro allows symlink but it MUST be the whole collection(e.g. `src/content/docs`)
- starlight only way to put docs under a `docs/` path is to have another `docs/` folder under the collection one `src/content/docs` (resulting in `src/content/docs/docs`)

If any of the issues above is improve we could potentially move the docs back here or reduce at least some nesting

---

### Overview (`website/README.md`)

# Starlight Starter Kit: Basics

[](https://starlight.astro.build)

```
npm create astro@latest -- --template starlight
```

[](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
[](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
[](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/basics)
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)

> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!

## 🚀 Project Structure

Inside of your Astro + Starlight project, you'll see the following folders and files:

```
.
├── public/
├── src/
│   ├── assets/
│   ├── content/
│   │   ├── docs/
│   │   └── config.ts
│   └── env.d.ts
├── astro.config.mjs
├── package.json
└── tsconfig.json
```

Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.

Images can be added to `src/assets/` and embedded in Markdown with a relative link.

Static assets, like favicons, can be placed in the `public/` directory.

## 🧞 Commands

All commands are run from the root of the project, from a terminal:

| Command                   | Action                                           |
| :------------------------ | :----------------------------------------------- |
| `npm install`             | Installs dependencies                            |
| `npm run dev`             | Starts local dev server at `localhost:4321`      |
| `npm run build`           | Build your production site to `./dist/`          |
| `npm run preview`         | Preview your build locally, before deploying     |
| `npm run astro ...`       | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI                     |

## 👀 Want to learn more?

Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).

---

### Overview (`.github/workflows/README.md`)

# TypeSpec Workflows

This directory contains the GitHub workflows used for TypeSpec repository CI/CD processes.

## Available Workflows

| Workflow                   | Description                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------- |
| `consistency.yml`          | Ensures code consistency, including changelog, spellcheck, formatting, and linting |
| `codeql.yml`               | Runs CodeQL analysis for code security                                             |
| `external-integration.yml` | Optional CI check that verifies compatibility with Azure/typespec-azure repository |

## TypeSpec-Azure Integration Check

The `external-integration.yml` workflow verifies that changes in the TypeSpec repository do not break compatibility with the Azure/typespec-azure repository, which depends on TypeSpec as a core dependency.

### How It Works

1. Clones the Azure/typespec-azure repository
2. Finds the "core" submodule that references microsoft/typespec
3. Updates that submodule to use the changes from the current PR
4. Runs the build and tests for the Azure/typespec-azure repository

### When It Runs

This check runs on:

- Pull requests to the main branch
- Manual triggers via workflow_dispatch

### What It Checks

- Whether the Azure/typespec-azure repository can build successfully with the changes from the PR
- Whether all tests in the Azure/typespec-azure repository pass with the changes

### Configuration

This is an optional check that won't block PRs from being merged. It only runs on Linux with Node LTS (24.x) to minimize resource usage while still catching compatibility issues.

---

### Overview (`eng/emitter-diff/README.md`)

# emitter-diff

A language-agnostic tool for **diffing the generated code produced by two versions of a
TypeSpec emitter**.

It runs the emitter's own regenerate command against a **baseline** source tree and a **head**
source tree, then shows the diff between the two generated outputs. Use it locally during
development and in CI on PRs.

The tool contains **zero language logic**. An emitter integrates by naming three things — its
regenerate command, the package directory to run it in, and the generated-code directory to diff —
either as flags or via a built-in `--emitter` preset.

## How it works

```text
   baseline tree ─► run <command> in <emitter-path> ─► snapshot <generated-code-path> ─┐
                                                                                        ├─► git diff ─► terminal / HTML
   head tree ─────► run <command> in <emitter-path> ─► snapshot <generated-code-path> ─┘
```

- A **source tree** is resolved for each side (`--baseline` / `--head`).
- The **`--command`** is run verbatim (tokenized to argv — no shell) inside
  `<tree>/<emitter-path>`. This is the emitter's _unmodified_ regenerate command; the tool does
  not reach into it.
- The `<emitter-path>/<generated-code-path>` subtree is snapshotted for each side and the
  two snapshots are diffed. `--generated-code-path` accepts **multiple roots** — an emitter that
  writes generated code to several directories (e.g. Go) passes a comma-separated list or repeats
  the flag; each root is snapshotted under its own relative path so outputs never collide.

Because the tool just runs a command, **any emitter with a regenerate script works** — no per-language
plugin code.

## Usage

```bash
# Using a built-in preset (fills in command + paths):
node eng/emitter-diff/src/cli.ts --emitter python --baseline gh:<sha>

# Fully explicit (no preset needed):
node eng/emitter-diff/src/cli.ts \
  --command "npm run regenerate" \
  --emitter-path packages/http-client-python \
  --generated-code-path tests/generated \
  --baseline gh:<sha>

# Multiple generated roots (e.g. Go writes several) — comma-separated (or repeat the flag):
node eng/emitter-diff/src/cli.ts \
  --command "npm run tspcompile" \
  --emitter-path packages/typespec-go \
  --generated-code-path test/http-specs,test/azure-http-specs \
  --baseline github:Azure/autorest.go@<sha>
```

> This tool is a set of plain `.ts` scripts — not an installed package. It runs through `node`
> (which executes TypeScript directly on the versions this repo supports), so there is nothing to
> build. Typecheck with `npx tsc -p eng/emitter-diff`.

> **Build your checkout first.** `--head` defaults to the current working tree, and the tool runs
> the regenerate command against it **as-is** — it never installs or builds your checkout (see
> [Command prep](#command-prep---setup)). Build the emitter for the head side before diffing; for
> **python** that's `npm run setup` in `packages/http-client-python` (builds the emitter and creates
> the venv `regenerate` requires). Only trees the tool fetches from GitHub are auto-prepared.

### Emitter config

| Flag                           | Meaning                                                                                                                                                                                                                                            |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--emitter <name>`             | Built-in preset that fills in the three fields below.                                                                                                                                                                                              |
| `--command <cmd>`              | Regenerate command, run verbatim in `--emitter-path`.                                                                                                                                                                                              |
| `--emitter-path <path>`        | Package dir (relative to a tree root) to run the command in.                                                                                                                                                                                       |
| `--generated-code-path <path>` | Generated-code dir (relative to `--emitter-path`) to diff. Accepts **multiple roots** — comma-separated (`a,b`) or by repeating the flag — for an emitter with several generated roots (e.g. Go); each is snapshotted under its own relative path. |

A preset supplies all three; each flag still overrides the preset value. To onboard a new language,
add a row to `EMITTER_DEFAULTS` in `src/registry.ts` — or just pass the three flags directly and
skip `--emitter`.

### Refs

| Syntax                            | Meaning                              |
| --------------------------------- | ------------------------------------ |
| `local:/path` or `./path`         | a local source folder (run in place) |
| `github:owner/repo@<sha\|branch>` | a GitHub source at a ref             |
| `gh:<sha\|branch>`                | this repo (origin remote) at a ref   |

`--head` defaults to the **current working tree**. `--baseline` defaults to the `upstream` remote's
repo at its default branch, falling back to `origin` (e.g. `github:microsoft/typespec@main`).

### Command prep (`--setup`)

The `--command` is run **as-is** — it does not install deps or build. Instead, prep is handled by
**`--setup`**, which runs **only in a tree the tool freshly fetched from GitHub** (a `gh:`/`github:`
ref). The current working tree and user-provided `local:` paths are assumed already built and are
**never touched** (so setup never mutates your checkout or a prepared CI worktree).

- A **preset** supplies sensible setup defaults, so `--emitter python --baseline gh:main` installs +
  builds the fetched baseline automatically (python: `npm install --ignore-scripts` → `npm run setup`;
  typescript: `pnpm install` → `npm run build`).
- Override with one or more `--setup <cmd>` (each runs in order, in `<tree>/<emitter-path>`), or
  disable entirely with `--no-setup`.

Each `--setup` command — like `--command` — is tokenized to argv and run **without a shell**, so
multi-step pipelines (`&&`, `|`) are not supported; pass repeated `--setup` flags instead.

### Common options

By default the tool writes a **clickable HTML report** (`emitter-diff.html`) into the work dir and
prints a `file://` link to it.

- `--baseline <ref>` / `--head <ref>`: the two source trees to compare.
- `--setup <cmd>` (repeatable) / `--no-setup`: prep commands for freshly fetched GitHub trees.
- `--work-dir <dir>`: scratch dir for snapshots (default: a fresh temp dir).
- `--sequential`: regenerate baseline then head one after another instead of in parallel. Useful on
  a single machine where running both at once oversubscribes the CPU (each regenerate already fans
  out across cores) or trips generator races.
- `--ci`: disable the local baseline-output cache (intended for CI).
- `--html <file>`: write the rendered HTML report to this path.
- `--md <file>`: write a Markdown report (collapsible per-file `diff` blocks) to this path. Handy for
  a CI job summary (`$GITHUB_STEP_SUMMARY`) or a PR comment body.
- `--no-group`: render every file separately in the HTML/Markdown reports. By default, files that
  share the same change — the same added/removed lines, even when the surrounding generated code
  differs — are merged into a single collapsible group (with the shared diff shown once and every
  once and every affected file listed), so a repeated change across many generated files is reviewed
  once instead of N times.
- `--fail-on-diff`: exit non-zero when output differs (exit `2` = diff present, `1` = hard error).
- `-- <args>`: everything after `--` is appended to `--command` verbatim on **both** sides, so the
  diff stays apples-to-apples. Use it to regenerate only a subset of tests by forwarding the
  regenerate script's own filter flags.

### Regenerating a subset of tests

The tool doesn't define its own test-filter flags — it forwards `-- <args>` to each emitter's
regenerate command, which owns the filtering. For the **Python** emitter (`regenerate.ts`):

- `-n, --name <pattern>`: case-insensitive substring match on package name.
- `-f, --flavor <azure|unbranded>`: limit to one flavor.
- `-j, --jobs <n>`: parallel job count.

```sh
# Only the authentication packages, azure flavor
node ../../eng/emitter-diff/src/cli.ts --emitter python -- --name authentication --flavor azure

# Via the package script (first `--` is npm's, second is emitter-diff's passthrough separator)
npm run diff-spector-tests -- -- --name type/array
```

`--name` filters the spec set already bundled in the package's `node_modules`
(`@azure-tools/azure-http-specs` + `@typespec/http-specs`); it does not point the test set at an
arbitrary folder or ref. Other emitters expose their own filter flags — pass whatever their
regenerate command accepts.

## CI integration

`.github/workflows/ci-emitter-diff-<lang>.yml` runs on PRs that touch the language emitter or this
tool. The **baseline** is the base-branch commit the PR is based on (the `git merge-base` with the
target branch). Because the tool runs the regenerate command as-is, the workflow **prepares both
trees** (installs deps, builds the emitter, creates any venv) before invoking the tool, then:

- writes a **job summary** with the rendered diff,
- relays a **sticky PR comment** for fork and same-repository PRs, and
- uploads the rendered **HTML report** as an artifact.

**Informational:** the check **always passes unless the tool hits a real tool/build error** — a
generated-output diff does not fail the PR. CI runs the tool without `--fail-on-diff`, so a diff
still exits `0`; only a non-zero exit (a build/venv/generate failure) fails the job.

**Fork PR comments use an artifact relay.** The Python producer stays on `pull_request` with only
`contents: read` and checkout credentials not persisted. It uploads a small
**emitter-diff-python-comment** JSON artifact (retained for one day), including a failure message
if setup or generation fails. Fork runs may require maintainer approval under the repository's
Actions policy.

`.github/workflows/ci-emitter-diff-python-commenter.yml` listens for completed **python / emitter diff**
runs using `workflow_run`, with only `actions: read` and `pull-requests: write`. It never checks out,
builds, or executes PR code or downloaded scripts. The artifact supplies only bounded comment text;
the listener resolves exactly one open PR using the trusted run's head repository, branch, and SHA.
It ignores artifact PR numbers and markers, skips stale/closed/ambiguous PRs, and rechecks the current
head before posting. It paginates comments and updates only its fixed-marker, GitHub Actions bot-owned
comment. Per-branch serialization and a trusted run stamp prevent an older run overwriting a newer
comment.

Cancelled or skipped runs do not post comments. A failed run without a comment artifact produces
an explicit warning; missing artifacts from successful runs, malformed payloads, and API/download
errors fail the listener rather than silently reporting success.

To review a fork PR's diff, open its **python / emitter diff** check and follow **Details** to the
workflow run. Read the rendered diff in the job summary or download **emitter-diff-html** from
the run's **Artifacts** section (retained for seven days). Manual `workflow_dispatch` runs also
produce reports without posting PR comments.

The listener must land on the repository's **default branch** before GitHub will trigger it.
An existing PR also needs a new producer run using the updated workflow revision; rerunning an old
run retains its original revision. After these workflow changes land, updating the PR branch from
its target branch and pushing starts a new run with the comment artifact. Local listener tests do
not establish that hosted fork commenting works before that default-branch activation.

## Adding a new language

Either add a preset row to `EMITTER_DEFAULTS` (`src/registry.ts`):

```ts
rust: {
  command: "npm run tspcompile",
  emitterPath: "packages/typespec-rust",
  generatedCodePath: "test/generated",
},
```

…or skip the preset entirely and pass `--command` / `--emitter-path` /
`--generated-code-path` directly. Either way, ensure each side's tree can actually run the
command (see **Command prep** above). The orchestrator, ref resolver, and diff engine need no
changes.

## Notes & limitations

- `--html` renders a self-contained, GitHub-style HTML report (inline CSS, no external requests).
  `--md` renders a Markdown report (collapsible per-file `diff` blocks) suitable for a CI job
  summary or PR comment. Both reports group files that share the same change into one block by
  default (`--no-group` to disable), so reviewing a repeated diff is a one-time effort. The diff
  itself is produced by `git diff --no-index`; the tool leans on only a couple of small repo dev
  dependencies (`execa`, `picocolors`) for process spawning and terminal coloring.
- For github refs (including fork repos), the resolver uses a detached, commit-keyed cached git
  worktree under the temp directory, created from an isolated cache repo (not from your active
  checkout). Repeated runs on the same commit reuse it.
- Spec inputs come from each side's own dependencies (e.g. `node_modules/@typespec/http-specs`).
  Spec versions rarely change, so any drift between baseline/head is treated as acceptable noise.

---

### Overview (`icons/raw/readme.md`)

# TypeSpec Raw Svg Icons

Those are the raw TypeSpec icons with text still has text. It can be used to easily convert the text to path with different font and different positions.

---

### Overview (`packages/astro-utils/README.md`)

# TypeSpec Astro Utils

This is a bunch of tools for various components of astro(shiki, starlight, expressive code) that is shared across typespec.io and azure.github.io/typpespec-azure website.

**DO NOT PUBLISH**

---

### Overview (`packages/best-practices/README.md`)

# TypeSpec Best Practices

**WORK IN PROGRESS This is not ready for consumption**

Set of linter rules to enforce TypeSpec best practices

---

### Overview (`packages/compiler/README.md`)

# TypeSpec compiler and CLI

This package implements the core of the [TypeSpec](https://github.com/microsoft/typespec)
compiler and its command-line interface.

## See also

- [TypeSpec Getting Started](https://github.com/microsoft/typespec#getting-started)
- [TypeSpec Website](https://typespec.io)

---

### Overview (`packages/events/README.md`)

# @typespec/events

TypeSpec library providing events bindings

## Install

```bash
npm install @typespec/events
```

## Decorators

### TypeSpec.Events

- [`@contentType`](#@contenttype)
- [`@data`](#@data)
- [`@events`](#@events)

#### `@contentType`

Specifies the content type of the event envelope, event body, or event payload.
When applied to an event payload, that field must also have a corresponding `@data`
decorator.

```typespec
@TypeSpec.Events.contentType(contentType: valueof string)
```

##### Target

`UnionVariant | ModelProperty`

##### Parameters

| Name        | Type             | Description                                     |
| ----------- | ---------------- | ----------------------------------------------- |
| contentType | `valueof string` | The content type of the event or event payload. |

##### Examples

```typespec
@events
union MixedEvents {
  @contentType("application/json")
  message: {
    id: string,
    text: string,
  },
}
```

###### Specify the content type of the event payload.

```typespec
@events
union MixedEvents {
  {
    done: true,
  },
  {
    done: false,
    @data @contentType("text/plain") value: string,
  },
}
```

#### `@data`

Identifies the payload of an event.
Only one field in an event can be marked as the payload.

```typespec
@TypeSpec.Events.data
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

```typespec
@events
union MixedEvents {
  {
    metadata: Record<string>,
    @data payload: string,
  },
}
```

#### `@events`

Specify that this union describes a set of events.

```typespec
@TypeSpec.Events.events
```

##### Target

`Union`

##### Parameters

None

##### Examples

```typespec
@events
union MixedEvents {
  pingEvent: string,
  doneEvent: "done",
}
```

---

### Overview (`packages/graphql/README.md`)

# @typespec/graphql

TypeSpec library for emitting GraphQL

## Install

```bash
npm install @typespec/graphql
```

## Emitter usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/graphql
```

2. Via the config

```yaml
emit:
  - "@typespec/graphql"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/graphql"
options:
  "@typespec/graphql":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/graphql`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `output-file`

**Type:** `string`

Name of the output file.
Output file will interpolate the following values:

- schema-name: Name of the schema if multiple

Default: `{schema-name}.graphql`

Example Single schema

- `schema.graphql`

Example Multiple schemas

- `Org1.Schema1.graphql`
- `Org1.Schema2.graphql`

### `new-line`

**Type:** `"crlf" | "lf"`

**Default:** `"lf"`

Set the newLine character for emitting files.

### `omit-unreachable-types`

**Type:** `boolean`

Omit unreachable types.
By default all types declared under the schema namespace will be included.
With this flag on only types references in an operation will be emitted.

## Decorators

### TypeSpec.GraphQL

- [`@compose`](#@compose)
- [`@graphqlInterface`](#@graphqlinterface)
- [`@mutation`](#@mutation)
- [`@operationFields`](#@operationfields)
- [`@query`](#@query)
- [`@schema`](#@schema)
- [`@specifiedBy`](#@specifiedby)
- [`@subscription`](#@subscription)

#### `@compose`

Specify the GraphQL interfaces that should be implemented by a model.
The interfaces must be decorated with the `@graphqlInterface` decorator,
and all of the interfaces' properties must be present and compatible.

```typespec
@TypeSpec.GraphQL.compose(...interfaces: Model[])
```

##### Target

`Model`

##### Parameters

| Name       | Type      | Description                                                                 |
| ---------- | --------- | --------------------------------------------------------------------------- |
| interfaces | `Model[]` | The models to compose into the target, each emitted as a GraphQL interface. |

##### Examples

```typespec
@graphqlInterface(#{ interfaceOnly: true })
model Node {
  id: string;
}

@compose(Node)
model User {
  ...Node;
  name: string;
}
```

#### `@graphqlInterface`

Mark this model as a GraphQL Interface. Interfaces can be implemented by other models
using the `@compose` decorator.

```typespec
@TypeSpec.GraphQL.graphqlInterface(options?: valueof { interfaceOnly: boolean })
```

##### Target

`Model`

##### Parameters

| Name    | Type            | Description                                                                                                                                                                                                                                                           |
| ------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| options | `valueof {...}` | .interfaceOnly When true, the model will only be emitted as an interface<br />(no "Interface" suffix is added to the name). Use this for abstract interfaces that<br />will never be used directly as output/input types (e.g., Node, Connection). Defaults to false. |

##### Examples

```typespec
@graphqlInterface(#{ interfaceOnly: true })
model Node {
  id: string;
}

@compose(Node)
model User {
  ...Node;
  name: string;
}
// Emits: interface Node { id: String! }
//        type User implements Node { id: String!; name: String! }
```

#### `@mutation`

Specify the GraphQL Operation kind for the target operation to be `MUTATION`.

```typespec
@TypeSpec.GraphQL.mutation
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@mutation op createUser(name: string): User;
```

#### `@operationFields`

Assign one or more operations or interfaces to act as fields with arguments on a model.
The operations become fields on the GraphQL type with their parameters as arguments.

```typespec
@TypeSpec.GraphQL.operationFields(...operations: Operation | Interface[])
```

##### Target

`Model`

##### Parameters

| Name       | Type                       | Description                                                                  |
| ---------- | -------------------------- | ---------------------------------------------------------------------------- |
| operations | `Operation \| Interface[]` | The operations, or interfaces of operations, to add to the target as fields. |

##### Examples

```typespec
op followers(query: string): Person[];

@operationFields(followers)
model Person {
  name: string;
}
// Emits: type Person { name: String!; followers(query: String!): [Person!]! }
```

#### `@query`

Specify the GraphQL Operation kind for the target operation to be `QUERY`.

```typespec
@TypeSpec.GraphQL.query
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@query op getUser(id: string): User;
```

#### `@schema`

Mark this namespace as describing a GraphQL schema and configure schema properties.
All types and operations within the namespace will be emitted to a single GraphQL schema file.

```typespec
@TypeSpec.GraphQL.schema(options?: valueof TypeSpec.GraphQL.Schema.SchemaOptions)
```

##### Target

`Namespace`

##### Parameters

| Name    | Type                                      | Description                               |
| ------- | ----------------------------------------- | ----------------------------------------- |
| options | [valueof `SchemaOptions`](#schemaoptions) | Options for the schema, such as its name. |

##### Examples

```typespec
@schema(#{ name: "MyAPI" })
namespace MyAPI {
  model User {
    id: string;
    name: string;
  }
  @query op getUser(id: string): User;
}
// Emits: MyAPI.graphql
```

#### `@specifiedBy`

Provide a specification URL for a custom GraphQL scalar type.
This maps to the `@specifiedBy` directive in the emitted GraphQL schema.

```typespec
@TypeSpec.GraphQL.specifiedBy(url: valueof url)
```

##### Target

`Scalar`

##### Parameters

| Name | Type          | Description                          |
| ---- | ------------- | ------------------------------------ |
| url  | `valueof url` | URL to the scalar type specification |

##### Examples

```typespec
@specifiedBy("https://scalars.graphql.org/andimarek/date-time")
scalar DateTime extends utcDateTime;
```

#### `@subscription`

Specify the GraphQL Operation kind for the target operation to be `SUBSCRIPTION`.

```typespec
@TypeSpec.GraphQL.subscription
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@subscription op onUserCreated(): User;
```

---

### Overview (`packages/html-program-viewer/README.md`)

# TypeSpec Html Program viewer emitter.

## See also

- [TypeSpec Getting Started](https://github.com/microsoft/typespec#getting-started)
- [TypeSpec Website](https://typespec.io)
- [TypeSpec for the OpenAPI Developer](https://github.com/microsoft/typespec/blob/main/docs/typespec-for-openapi-dev.md)

---

### Overview (`packages/http-canonicalization/README.md`)

# @typespec/http-canonicalization

** WARNING: THIS PACKAGE IS EXPERIMENTAL AND WILL CHANGE **

Utilities for emitters and tooling that need to understand type shapes in the HTTP protocol. The canonicalizer produces a mutated type graph specifying shapes in the language and on the wire, as well as groups together relevant HTTP metadata from various compiler APIs in a convenient package.

## Why you might use it

- Get HTTP request and response shapes.
- Apply visibility transforms.
- Understand how types are serialized to HTTP.
- Get tests to determine how to discriminate non-discriminated unions.

## Installation

```bash
pnpm add @typespec/http-canonicalization
```

Peer dependencies `@typespec/compiler` and `@typespec/http` must be installed.

## Quick start

TypeSpec service definition:

```typespec
import "@typespec/http";

model Foo {
  @visibility(Lifecycle.Read)
  @encode(DateTimeKnownEncoding.rfc7231)
  createdAt: utcDateTime;

  @visibility(Lifecycle.Create)
  name: string;
}

@route("/foo")
@post
op createFoo(@body foo: Foo): Foo;
```

Emitter-side usage:

```ts
import { $ } from "@typespec/compiler/typekit";
import { HttpCanonicalizer } from "@typespec/http-canonicalization";

const tk = $(program);
const canonicalizer = new HttpCanonicalizer(tk);
const http = canonicalizer.canonicalize(op);
const body = http.requestParameters.body!.type;
// body.type.languageType.name === "FooCreate"
// body.type.visibleProperties => only "name"

const response = http.responses[0];
// response.type.languageType.properties has both "name" and "createdAt"
// response.responses[0].headers?.etag captures header metadata
```

## What the result tells you

- **Models and properties**: `languageType` reflects the shape visible to generated code, while `wireType` describes the payload sent over the network. Properties removed for the selected visibility remain in `properties` but carry an `intrinsic.never` language type so you can detect deletions.
- **Scalars**: Each scalar includes a `codec` (for example `rfc7231` for date headers) and may change its wire type (e.g., `int32` -> `float64`) to match HTTP expectations.
- **Operations**: Requests expose grouped `headers`, `query`, `path`, and `body` parameters. Responses list status codes, per-content-type payloads, and derived body information (single, multipart, or file payloads) along with metadata such as content type properties and filenames.
- **Unions**: Variant tests contain ordered type guards (primitive checks before object checks) and literal discriminants. If variants cannot be distinguished (for example, two object models with identical shapes), the canonicalizer throws so you can surface a clear error.

## API reference

### OperationHttpCanonicalization

- Canonicalizes operations by deriving HTTP-specific request and response shapes and tracks the language and wire projections for each operation.
- `requestParameters`: Canonicalized request parameters grouped by location.
- `requestHeaders`: Canonicalized header parameters for the request.
- `queryParameters`: Canonicalized query parameters for the request.
- `pathParameters`: Canonicalized path parameters for the request.
- `responses`: Canonicalized responses produced by the operation.
- `path`: Concrete path for the HTTP operation.
- `uriTemplate`: URI template used for path and query expansion.
- `parameterVisibility`: Visibility applied when canonicalizing request parameters.
- `returnTypeVisibility`: Visibility applied when canonicalizing response payloads.
- `method`: HTTP method verb for the operation.
- `name`: Name assigned to the canonicalized operation.
- `languageType`: Mutated language type for this operation.
- `wireType`: Mutated wire type for this operation.

### ModelHttpCanonicalization

- Canonicalizes models for HTTP and supplies language and wire variants along with visibility-aware metadata.
- `isDeclaration`: Indicates if the canonicalization wraps a named TypeSpec declaration.
- `codec`: Codec chosen to transform language and wire types for this model.
- `languageType`: Possibly mutated language type for the model.
- `wireType`: Possibly mutated wire type for the model.
- `visibleProperties`: Canonical properties visible under the current visibility options.

### ModelPropertyHttpCanonicalization

- Canonicalizes model properties, tracking HTTP metadata, visibility, and codecs while adjusting types per location.
- `isDeclaration`: Indicates if this property corresponds to a named declaration.
- `isVisible`: Whether the property is visible with the current visibility options.
- `codec`: Codec used to transform the property's type between language and wire views.
- `isQueryParameter`: True when the property is a query parameter.
- `queryParameterName`: Query parameter name when applicable.
- `isHeader`: True when the property is an HTTP header.
- `headerName`: Header name when the property is a header.
- `isPathParameter`: True when the property is a path parameter.
- `pathParameterName`: Path parameter name when applicable.
- `explode`: Whether structured values should use explode semantics.
- `languageType`: Possibly mutated language type for the property.
- `wireType`: Possibly mutated wire type for the property.

### ScalarHttpCanonicalization

- Canonicalizes scalar types by applying encoding-specific mutations driven by codecs.
- `options`: Canonicalization options in effect for the scalar.
- `codec`: Codec responsible for transforming the scalar into language and wire types.
- `isDeclaration`: Indicates whether the scalar is a named TypeSpec declaration.
- `languageType`: Possibly mutated language type for the scalar.
- `wireType`: Possibly mutated wire type for the scalar.

### UnionHttpCanonicalization

- Canonicalizes union types, tracking discriminators, envelope structures, and runtime variant tests for both language and wire projections.
- `options`: Canonicalization options guiding union transformation.
- `isDeclaration`: Indicates if the union corresponds to a named declaration.
- `isDiscriminated`: True when `@discriminator` is present on the union.
- `envelopeKind`: Envelope structure used for discriminated unions.
- `discriminatorProperty`: Canonicalized discriminator property for envelope unions.
- `variantDescriptors`: Descriptors describing each canonicalized variant.
- `languageVariantTests`: Runtime tests used to select a variant for language types.
- `wireVariantTests`: Runtime tests used to select a variant for wire types.
- `discriminatorPropertyName`: Name of the discriminator property when present.
- `envelopePropertyName`: Name of the envelope property when present.
- `visibleVariants`: Variants that remain visible under the current visibility rules.
- `languageType`: Potentially mutated language type for this union.
- `wireType`: Potentially mutated wire type for this union.

### UnionVariantHttpCanonicalization

- Canonicalizes individual union variants for HTTP, removing hidden variants and exposing mutated representations.
- `options`: Canonicalization options.
- `isDeclaration`: Indicates if the variant corresponds to a named declaration.
- `isVisible`: Whether the variant is visible under the current visibility options.
- `languageType`: Possibly mutated language type for this variant.
- `wireType`: Possibly mutated wire type for this variant.

### IntrinsicHttpCanonicalization

- Canonicalizes intrinsic types for HTTP, producing language and wire projections directed by the active options.
- `options`: Canonicalization options.
- `isDeclaration`: Indicates if this intrinsic represents a named declaration.
- `languageType`: Possibly mutated language type for this intrinsic.
- `wireType`: Possibly mutated wire type for this intrinsic.

### LiteralHttpCanonicalization

- Canonicalizes literal types for HTTP, yielding language and wire variants for string, number, and boolean literals.
- `options`: Canonicalization options.
- `isDeclaration`: Indicates if the literal is a named declaration (always false for literals).
- `languageType`: Possibly mutated language type for this literal.
- `wireType`: Possibly mutated wire type for this literal.

---

### Overview (`packages/http-client-csharp/readme.md`)

# @typespec/http-client-csharp

TypeSpec library for emitting Http Client libraries for C#.

## Install

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

## Usage

### Prerequisite

- Install [Node.js](https://nodejs.org/download/) 20 or above. (Verify by running `node --version`)
- Install [**.NET 8.0 SDK**](https://dotnet.microsoft.com/download/dotnet/8.0) for your specific platform. (or a higher version)

### Customizing Generated Code

For detailed instructions on how to customize the generated C# code, see the [Customization Guide](https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/.tspd/docs/customization.md).

### Experimental types and members

Use `@TypeSpec.HttpClient.experimental` to assign a public diagnostic ID to a generated
type or member and identify experiments used by its implementation:

```typespec
import "@typespec/http-client";

@TypeSpec.HttpClient.experimental(#{
  emitterScope: "@typespec/http-client-csharp",
  diagnosticId: "C",
  dependsOn: #["A", "B"],
})
op bar(): void;
```

The C# emitter adds `[Experimental("C")]` to the corresponding generated declaration:

| TypeSpec target                                       | Generated C# target                                           |
| ----------------------------------------------------- | ------------------------------------------------------------- |
| Model                                                 | Model class or struct                                         |
| Model property                                        | Property                                                      |
| Enum or union emitted as an enum                      | Enum or extensible-enum struct                                |
| Enum member or union variant emitted as an enum value | Enum field or extensible-enum property                        |
| Operation                                             | Synchronous and asynchronous protocol and convenience methods |
| Namespace or interface emitted as a client            | Client class                                                  |

For example, models and their properties can be separate experiments:

```typespec
@TypeSpec.HttpClient.experimental(#{ diagnosticId: "MODEL001" })
model Preview {
  @TypeSpec.HttpClient.experimental(#{ diagnosticId: "PROPERTY001" })
  value?: string;
}
```

Model factory methods expose the model's diagnostic. Partial serialization declarations
do not repeat the model attribute. Generated code suppresses diagnostics when referring
to source-annotated experimental types and members, so serialization, factories, and client
implementations can compile without changing the experimental status of other public APIs.

Suppressions surround only the member declarations or serialization blocks that need them,
including parameter and return types, generic arguments, and implementation references.
Explicit type-level `dependsOn` entries and base-type dependencies can require a type-wide
scope. References within a declaration carrying the same experimental diagnostic ID,
including its other partial declarations, do not need an additional suppression.
These suppressions do not affect diagnostics in consumer code or separate custom files.

Dependencies identify diagnostics rather than individual types: one diagnostic can apply
to multiple types or members, including those defined in external libraries. For externally
mapped types, source `@experimental` metadata is retained for generated-reference suppressions;
the emitter does not generate the external declaration or add attributes to its library.
This also covers client parameters exposed through generated settings and options properties.
Other external experiments require explicit `dependsOn` entries. They are not discovered by reflection.

Both metadata fields are optional. Without `diagnosticId`, no public experimental attribute
is added. Without `dependsOn`, no additional dependency diagnostics are requested; generated
references to source-annotated experiments are still handled. Emitter scopes apply to both fields.

Diagnostic IDs must be single C# warning identifiers (ASCII letters, digits, and underscores,
not starting with a digit) or decimal warning numbers. Whitespace, punctuation, comments, and
line breaks are rejected with `invalid-experimental-diagnostic-id` before generating C#.
An `ExperimentalAttribute` on a customized partial client or method takes precedence over
the generated attribute, including a polyfilled `System.Diagnostics.CodeAnalysis.ExperimentalAttribute`
on older target frameworks. Generated parent-client accessors suppress a child client's custom
diagnostic without marking the parent or accessor as experimental.

Some TypeSpec declarations have no corresponding C# declaration, such as scalars or unions
erased to built-in C# types without an explicit external mapping. C# also does not allow `ExperimentalAttribute` on parameters.
The emitter reports `experimental-target-not-supported` for these annotations instead of
silently dropping them or assigning their diagnostic to an unrelated API.

Models referenced by a union retain their own experimental metadata. Annotate the model
declaration, not the union variant that references it: a model variant has no separate C#
declaration on which to place an attribute.

Graduation is an explicit source change: dependencies becoming generally available, or
removing entries from `dependsOn`, does not remove `[Experimental("C")]`. Remove the
declaration's `@experimental` decorator when the public API is ready to graduate.

## Emitter usage

1. Via the command line

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

2. Via the config

```yaml
emit:
  - "@typespec/http-client-csharp"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/http-client-csharp"
options:
  "@typespec/http-client-csharp":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/http-client-csharp`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `api-version`

**Type:** `string | object`

Use this flag if you would like to generate the sdk only for a specific version. Default value is the latest version. Also accepts values `latest` and `all`. For multi-service packages, provide a map from each service namespace to its desired version. Nested namespaces must be represented as nested objects in `tspconfig.yaml`; services not listed default to their latest version.

**Options:**

- `string`
- `object`

### `generate-protocol-methods`

**Type:** `boolean`

Set to `false` to skip generation of protocol methods. The default value is `true`.

### `generate-convenience-methods`

**Type:** `boolean`

Set to `false` to skip generation of convenience methods. The default value is `true`.

### `unreferenced-types-handling`

**Type:** `"removeOrInternalize" | "internalize" | "keepAll"`

Defines the strategy on how to handle unreferenced types. The default value is `removeOrInternalize`.

### `new-project`

**Type:** `boolean`

Set to `true` to overwrite the csproj if it already exists. The default value is `false`.

### `save-inputs`

**Type:** `boolean`

Set to `true` to save the `tspCodeModel.json` and `Configuration.json` files that are emitted and used as inputs to the generator. The default value is `false`.

### `package-name`

**Type:** `string`

Define the package name. If not specified, the first namespace defined in the TypeSpec is used as the package name.

### `debug`

**Type:** `boolean`

Set to `true` to automatically attempt to attach to a debugger when executing the C# generator. The default value is `false`.

### `logLevel`

**Type:** `"info" | "debug" | "verbose"`

Set the log level for which to collect traces. The default value is `info`.

### `disable-xml-docs`

**Type:** `boolean`

Set to `true` to disable XML documentation generation. The default value is `false`.

### `disable-roslyn-reduce`

**Type:** `boolean`

Set to `true` to skip the Roslyn reduce (simplification) post-processing step. This speeds up generation and is useful when iterating quickly. The default value is `false`.

### `generator-name`

**Type:** `string`

The name of the generator. By default this is set to `ScmCodeModelGenerator`. Generator authors can set this to the name of a generator that inherits from `ScmCodeModelGenerator`.

### `emitter-extension-path`

**Type:** `string`

Allows emitter authors to specify the path to a custom emitter package, allowing you to extend the emitter behavior. This should be set to `import.meta.url` if you are using a custom emitter.

### `plugins`

**Type:** `string[]`

Paths to generator plugin assemblies (DLLs) or directories containing plugin assemblies. Each plugin must contain a class that extends `GeneratorPlugin`. Paths may be absolute or relative to the resolved `emitter-output-dir`. For example, to load plugins that live in a `codegen` folder under the output directory:

```yaml
options:
  "@typespec/http-client-csharp":
    plugins:
      - "codegen/MyPlugin.dll" # file relative to emitter-output-dir
      - "codegen" # directory containing plugin assemblies
      - "/abs/path/to/MyPlugin.dll" # absolute path used as-is
```

### `license`

**Type:** `object { name, company, link, header, description }`

License information for the generated client code.

**Properties:**

| Name          | Type     | Default | Description |
| ------------- | -------- | ------- | ----------- |
| `name`        | `string` |         |             |
| `company`     | `string` |         |             |
| `link`        | `string` |         |             |
| `header`      | `string` |         |             |
| `description` | `string` |         |             |

### `sdk-context-options`

**Type:** `object`

The SDK context options that implement the `CreateSdkContextOptions` interface from the [`@azure-tools/typespec-client-generator-core`](https://www.npmjs.com/package/@azure-tools/typespec-client-generator-core) package to be used by the CSharp emitter.

## Decorators

### TypeSpec.HttpClient.CSharp

- [`@dynamicModel`](#@dynamicmodel)

#### `@dynamicModel`

Marks a model or namespace as dynamic, indicating it should generate dynamic model code.
Can be applied to Model or Namespace types.

```typespec
@TypeSpec.HttpClient.CSharp.dynamicModel
```

##### Target

`Model | Namespace`

##### Parameters

None

##### Examples

```tsp
@dynamicModel
model Pet {
  name: string;
  kind: string;
}

@dynamicModel
namespace PetStore {
  model Dog extends Pet {
    breed: string;
  }
}
```

---

### Overview (`packages/http-client-java/README.md`)

# @typespec/http-client-java

TypeSpec library for emitting Java client from the TypeSpec REST protocol binding

## Install

```bash
npm install @typespec/http-client-java
```

## Usage

### Prerequisite

Install [Node.js](https://nodejs.org/) 20 or above. (Verify by running `node --version`)

Install [Java](https://docs.microsoft.com/java/openjdk/download) 17 or above. (Verify by running `java --version`)

Maven is needed to build the generated client, but not to run the emitter.

## Emitter usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/http-client-java
```

2. Via the config

```yaml
emit:
  - "@typespec/http-client-java"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/http-client-java"
options:
  "@typespec/http-client-java":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/http-client-java`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `license`

**Type:** `object`

License information for the generated client code.

### `dev-options`

**Type:** `object`

Developer options for http-client-java emitter.

---

### Overview (`packages/http-client-js/README.md`)

# @typespec/http-client-js

TypeSpec library for emitting Http Client libraries for JavaScript/TypeScript

## Install

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

## Emitter usage

1. Via the command line

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

2. Via the config

```yaml
emit:
  - "@typespec/http-client-js"
```

The config can be extended with options as follows:

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

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/http-client-js`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `package-name`

**Type:** `string`

**Default:** `"test-package"`

Name of the package as it will be in package.json

---

### Overview (`packages/http-client-python/README.md`)

# @typespec/http-client-python

TypeSpec emitter for Python SDKs

## Install

```bash
npm install @typespec/http-client-python
```

## Emitter usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/http-client-python
```

2. Via the config

```yaml
emit:
  - "@typespec/http-client-python"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/http-client-python"
options:
  "@typespec/http-client-python":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/http-client-python`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `api-version`

**Type:** `undefined`

Use this flag if you would like to generate the sdk only for a specific version. Default value is the latest version. Also accepts values `latest` and `all`. For multi-service packages, provide a map from each service namespace's full name to its desired version; services not listed default to their latest version.

### `license`

**Type:** `object`

License information for the generated client code.

### `package-version`

**Type:** `string`

The version of the package.

### `package-name`

**Type:** `string`

The name of the package.

### `generate-packaging-files`

**Type:** `boolean`

Whether to generate packaging files. Packaging files refer to the `setup.py`, `README`, and other files that are needed to package your code.

### `packaging-files-dir`

**Type:** `string`

If you are using a custom packaging files directory, you can specify it here. We won't generate with the default packaging files we have.

### `packaging-files-config`

**Type:** `object`

If you are using a custom packaging files directory, and have additional configuration parameters you want to pass in during generation, you can specify it here. Only applicable if `packaging-files-dir` is set.

### `package-pprint-name`

**Type:** `string`

The name of the package to be used in pretty-printing. Will be the name of the package in `README` and pprinting of `setup.py`.

### `head-as-boolean`

**Type:** `boolean`

Whether to return responses from HEAD requests as boolean. Defaults to `true`.

### `enable-sse-reconnect`

**Type:** `boolean`

**Default:** `false`

Whether to generate automatic reconnection support for Server-Sent Events (SSE). Defaults to `false`: SSE streams end when the response reaches EOF, without sending another request. Set to `true` to generate reconnect callbacks, retry delays, and `Last-Event-ID` resumption. SSE event IDs and retry metadata are parsed in either mode. Transport errors still propagate to the caller.

Enable this generation-time option in `tspconfig.yaml`:

```yaml
emit:
  - "@typespec/http-client-python"
options:
  "@typespec/http-client-python":
    enable-sse-reconnect: true
```

### `use-pyodide`

**Type:** `boolean`

Whether to generate using `pyodide` instead of `python`. If there is no python installed on your device, we will default to using pyodide to generate the code.

### `validate-versioning`

**Type:** `boolean`

Whether to validate the versioning of the package. Defaults to `true`. If set to `false`, we will not validate the versioning of the package.

### `generation-subdir`

**Type:** `string`

The subdirectory (relative to the package namespace folder) to generate the code in. Use this to keep emitter-generated code separate from hand-written/customized code, so regeneration only overwrites the subdirectory and leaves your customizations untouched. If not specified, the code is generated directly in the package namespace folder. Note: if you're using this flag, you will need to add and maintain the versioning file (`_version.py`) yourself.

Example: for `namespace: azure.storage.blob` with `generation-subdir: _generated`, generated code lands in `azure/storage/blob/_generated/` while your customized code lives in `azure/storage/blob/`. A typical `tspconfig.yaml` looks like:

```yaml
options:
  "@azure-tools/typespec-python":
    emitter-output-dir: "{output-dir}/{service-dir}/azure-storage-blob"
    namespace: "azure.storage.blob"
    generation-subdir: "_generated"
```

### `keep-setup-py`

**Type:** `boolean`

Whether to keep the existing `setup.py` when `generate-packaging-files` is `true`. If set to `false` and by default, `pyproject.toml` will be generated instead. To generate `setup.py`, use `basic-setup-py`.

### `generate-typeddict`

**Type:** `boolean`

Whether to add TypedDict typing for JSON dictionary input in `models-mode: dpg`, instead of accepting only generic JSON. This enriches the typing on the existing overloads rather than adding another request-body overload. Defaults to `true`.

### `keep-pyproject-fields`

**Type:** `object`

Which manually customized `[project]` fields to preserve in an existing `pyproject.toml` instead of overwriting them on regeneration. Set a field to `true` to keep it. By default no fields are preserved.

### `clear-output-folder`

**Type:** `boolean`

Whether to clear the output folder before generating the code. Defaults to `false`.

### `emit-yaml-only`

**Type:** `boolean`

Emit YAML code model only, without running Python generator. For batch processing.

---

### Overview (`packages/http-server-csharp/README.md`)

# @typespec/http-server-csharp

TypeSpec service code generator for c-sharp

## Install

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

## Emitter 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

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/http-server-csharp`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `skip-format`

**Type:** `boolean`

**Default:** `false`

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

### `output-type`

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

**Default:** `"all"`

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

### `emit-mocks`

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

**Default:** `"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`

**Default:** `false`

Configure a Swagger UI endpoint in the development configuration

### `openapi-path`

**Type:** `string`

**Default:** `null`

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`

**Default:** `false`

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

### `project-name`

**Type:** `string`

**Default:** `"ServiceProject"`

The name of the generated project.

### `http-port`

**Type:** `number`

**Default:** `null`

The service http port when hosting the project locally.

### `https-port`

**Type:** `number`

**Default:** `null`

The service https port when hosting the project locally.

### `collection-type`

**Type:** `"array" | "enumerable"`

**Default:** `"array"`

Specifies the collection type to use: 'array' or 'enumerable'. The default is 'array'.

---

### Overview (`packages/http-server-js/README.md`)

# @typespec/http-server-js

: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

## Install

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

## Emitter 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

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/http-server-js`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `express`

**Type:** `boolean`

**Default:** `false`

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.

### `datetime`

**Type:** `"temporal-polyfill" | "temporal" | "date-duration"`

**Default:** `"temporal-polyfill"`

The type of datetime models to use for TypeSpecs DateTime and Duration types.

### `omit-unreachable-types`

**Type:** `boolean`

**Default:** `false`

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`

If set to `true`, the emitter will not format the generated code using Prettier.

## 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.

---

### Overview (`packages/http-specs/README.md`)

# Http Specs

This package contains all the scenarios that should be supported by a client & service generator.

## Development

1. [FOLLOW THE MONOREPO INSTRUCTION](https://github.com/microsoft/typespec) to get the environment setup.
2. Scenarios should be in `./specs` folder

#### Writing scenarios

[Docs on writing scenarios specs](../spector/docs/writing-scenario-spec.md)

#### Writing mockapis

[Docs on writing mock apis](../spector/docs/writing-mock-apis.md)

#### Validate the scenarios are valid

```
pnpm run validate-scenarios
```

#### Validate the mock apis are valid

```
pnpm run validate-mock-apis
```

#### Start mock api server

This will start the server using the mock apis. When writing a mock api use this command to start the server.

```bash
pnpm run serve
```

#### Update version for release

```bash
pnpm change version --only "@typespec/http-specs"
```

Push the changes in branch named after the pattern `publish/xyz`. Once merged, the package will be auto-released.

---

### Overview (`packages/http/README.md`)

# @typespec/http

TypeSpec HTTP protocol binding

## Install

```bash
npm install @typespec/http
```

## Usage

Add the following in `tspconfig.yaml`:

```yaml
linter:
  extends:
    - "@typespec/http/all"
```

## RuleSets

Available ruleSets:

- `@typespec/http/all`

## Rules

| Name                                                                                                                        | Description                                                                               |
| --------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| [`@typespec/http/op-reference-container-route`](https://typespec.io/docs/libraries/http/rules/op-reference-container-route) | Check for referenced (`op is`) operations which have a @route on one of their containers. |

## Decorators

### TypeSpec.Http

- [`@body`](#@body)
- [`@bodyIgnore`](#@bodyignore)
- [`@bodyRoot`](#@bodyroot)
- [`@cookie`](#@cookie)
- [`@delete`](#@delete)
- [`@get`](#@get)
- [`@head`](#@head)
- [`@header`](#@header)
- [`@multipartBody`](#@multipartbody)
- [`@patch`](#@patch)
- [`@path`](#@path)
- [`@post`](#@post)
- [`@put`](#@put)
- [`@query`](#@query)
- [`@route`](#@route)
- [`@server`](#@server)
- [`@sharedRoute`](#@sharedroute)
- [`@statusCode`](#@statuscode)
- [`@useAuth`](#@useauth)

#### `@body`

Explicitly specify that this property type will be exactly the HTTP body.

This means that any properties under `@body` cannot be marked as headers, query parameters, or path parameters.
If wanting to change the resolution of the body but still mix parameters, use `@bodyRoot`.

```typespec
@TypeSpec.Http.body
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

```typespec
op upload(@body image: bytes): void;
op download(): {
  @body image: bytes;
};
```

#### `@bodyIgnore`

Specify that this property shouldn't be included in the HTTP body.
This can be useful when bundling metadata together that would result in an empty property to be included in the body.

```typespec
@TypeSpec.Http.bodyIgnore
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

```typespec
op upload(
  name: string,
  @bodyIgnore headers: {
    @header id: string;
  },
): void;
```

#### `@bodyRoot`

Specify that the body resolution should be resolved from that property.
By default the body is resolved by including all properties in the operation request/response that are not metadata.
This allows to nest the body in a property while still allowing to use headers, query parameters, and path parameters in the same model.

```typespec
@TypeSpec.Http.bodyRoot
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

```typespec
op upload(
  @bodyRoot user: {
    name: string;
    @header id: string;
  },
): void;
op download(): {
  @bodyRoot user: {
    name: string;
    @header id: string;
  };
};
```

#### `@cookie`

Specify this property is to be sent or received in the cookie.

```typespec
@TypeSpec.Http.cookie(cookieNameOrOptions?: valueof string | TypeSpec.Http.CookieOptions)
```

##### Target

`ModelProperty`

##### Parameters

| Name                | Type                                            | Description                                                                                                                                                                                       |
| ------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cookieNameOrOptions | `valueof string \| TypeSpec.Http.CookieOptions` | Optional name of the cookie in the cookie or cookie options.<br />By default the cookie name will be the property name converted from camelCase to snake_case. (e.g. `authToken` -> `auth_token`) |

##### Examples

```typespec
op read(@cookie token: string): {
  data: string[];
};
op create(
  @cookie({
    name: "auth_token",
  })
  data: string[],
): void;
```

###### Implicit header name

```typespec
op read(): {
  @cookie authToken: string;
}; // headerName: auth_token
op update(@cookie AuthToken: string): void; // headerName: auth_token
```

#### `@delete`

Specify the HTTP verb for the target operation to be `DELETE`.

```typespec
@TypeSpec.Http.delete
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@delete op set(petId: string): void;
```

#### `@get`

Specify the HTTP verb for the target operation to be `GET`.

```typespec
@TypeSpec.Http.get
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@get op read(): string;
```

#### `@head`

Specify the HTTP verb for the target operation to be `HEAD`.

```typespec
@TypeSpec.Http.head
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@head op ping(petId: string): void;
```

#### `@header`

Specify this property is to be sent or received as an HTTP header.

```typespec
@TypeSpec.Http.header(headerNameOrOptions?: valueof string | TypeSpec.Http.HeaderOptions)
```

##### Target

`ModelProperty`

##### Parameters

| Name                | Type                                            | Description                                                                                                                                                                                                 |
| ------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| headerNameOrOptions | `valueof string \| TypeSpec.Http.HeaderOptions` | Optional name of the header when sent over HTTP or header options.<br />By default the header name will be the property name converted from camelCase to kebab-case. (e.g. `contentType` -> `content-type`) |

##### Examples

```typespec
op read(@header accept: string): {
  @header("ETag") eTag: string;
};
op create(
  @header({
    name: "X-Color",
    format: "csv",
  })
  colors: string[],
): void;
```

###### Implicit header name

```typespec
op read(): {
  @header contentType: string;
}; // headerName: content-type
op update(@header ifMatch: string): void; // headerName: if-match
```

#### `@multipartBody`

Specify that the target property is the body of a multipart request or response.

The property type must be a model or tuple whose members are all `HttpPart`, each describing one
part of the payload.

```typespec
@TypeSpec.Http.multipartBody
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

```tsp
op upload(
  @header `content-type`: "multipart/form-data",
  @multipartBody body: {
    fullName: HttpPart<string>;
    headShots: HttpPart<Image>[];
  },
): void;
```

#### `@patch`

Specify the HTTP verb for the target operation to be `PATCH`.

```typespec
@TypeSpec.Http.patch(options?: valueof TypeSpec.Http.PatchOptions)
```

##### Target

`Operation`

##### Parameters

| Name    | Type                                    | Description                      |
| ------- | --------------------------------------- | -------------------------------- |
| options | [valueof `PatchOptions`](#patchoptions) | Options for the PATCH operation. |

##### Examples

```typespec
@patch op update(pet: Pet): void;
```

###### Using MergePatch template for proper merge-patch semantics

```typespec
@patch op update(@body pet: MergePatchUpdate<Pet>): void;
```

#### `@path`

Explicitly specify that this property is to be interpolated as a path parameter.

```typespec
@TypeSpec.Http.path(paramNameOrOptions?: valueof string | TypeSpec.Http.PathOptions)
```

##### Target

`ModelProperty`

##### Parameters

| Name               | Type                                          | Description                                                    |
| ------------------ | --------------------------------------------- | -------------------------------------------------------------- |
| paramNameOrOptions | `valueof string \| TypeSpec.Http.PathOptions` | Optional name of the parameter in the URI template or options. |

##### Examples

```typespec
@route("/read/{explicit}/things/{implicit}")
op read(@path explicit: string, implicit: string): void;
```

#### `@post`

Specify the HTTP verb for the target operation to be `POST`.

```typespec
@TypeSpec.Http.post
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@post op create(pet: Pet): void;
```

#### `@put`

Specify the HTTP verb for the target operation to be `PUT`.

```typespec
@TypeSpec.Http.put
```

##### Target

`Operation`

##### Parameters

None

##### Examples

```typespec
@put op set(pet: Pet): void;
```

#### `@query`

Specify this property is to be sent as a query parameter.

```typespec
@TypeSpec.Http.query(queryNameOrOptions?: valueof string | TypeSpec.Http.QueryOptions)
```

##### Target

`ModelProperty`

##### Parameters

| Name               | Type                                           | Description                                                                     |
| ------------------ | ---------------------------------------------- | ------------------------------------------------------------------------------- |
| queryNameOrOptions | `valueof string \| TypeSpec.Http.QueryOptions` | Optional name of the query when included in the url or query parameter options. |

##### Examples

```typespec
op read(@query select: string, @query("order-by") orderBy: string): void;
op list(@query(#{ name: "id", explode: true }) ids: string[]): void;
```

#### `@route`

Defines the relative route URI template for the target operation as defined by [RFC 6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3)

`@route` can only be applied to operations, namespaces, and interfaces.

```typespec
@TypeSpec.Http.route(path: valueof string)
```

##### Target

`Namespace | Interface | Operation`

##### Parameters

| Name | Type             | Description                      |
| ---- | ---------------- | -------------------------------- |
| path | `valueof string` | URI template for this operation. |

##### Examples

###### Simple path parameter

```typespec
@route("/widgets/{id}") op getWidget(@path id: string): Widget;
```

###### Reserved characters

```typespec
@route("/files{+path}") op getFile(@path path: string): bytes;
```

###### Query parameter

```typespec
@route("/files") op list(select?: string, filter?: string): Files[];
@route("/files{?select,filter}") op listFullUriTemplate(select?: string, filter?: string): Files[];
```

#### `@server`

Specify an endpoint for this service. Multiple `@server` decorators can be used to specify multiple endpoints.

```typespec
@TypeSpec.Http.server(url: valueof string, description?: valueof string, parameters?: Record<unknown>)
```

##### Target

`Namespace`

##### Parameters

| Name        | Type              | Description                                             |
| ----------- | ----------------- | ------------------------------------------------------- |
| url         | `valueof string`  | Server endpoint                                         |
| description | `valueof string`  | Description of the endpoint                             |
| parameters  | `Record<unknown>` | Optional set of parameters used to interpolate the url. |

##### Examples

```typespec
@service
@server("https://example.com")
namespace PetStore;
```

###### With a description

```typespec
@service
@server("https://example.com", "Single server endpoint")
namespace PetStore;
```

###### Parameterized

```typespec
@server("https://{region}.foo.com", "Regional endpoint", {
  @doc("Region name")
  region?: string = "westus",
})
```

###### Multiple

```typespec
@service
@server("https://example.com", "Standard endpoint")
@server(
  "https://{project}.private.example.com",
  "Private project endpoint",
  {
    project: string,
  }
)
namespace PetStore;
```

#### `@sharedRoute`

`@sharedRoute` marks the operation as sharing a route path with other operations.

When an operation is marked with `@sharedRoute`, it enables other operations to share the same
route path as long as those operations are also marked with `@sharedRoute`.

`@sharedRoute` can only be applied directly to operations.

```typespec
@sharedRoute
@route("/widgets")
op getWidget(@path id: string): Widget;
```

```typespec
@TypeSpec.Http.sharedRoute
```

##### Target

`Operation`

##### Parameters

None

#### `@statusCode`

Specify the status code for this response. Property type must be a status code integer or a union of status code integer.

```typespec
@TypeSpec.Http.statusCode
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

```typespec
op read(): {
  @statusCode _: 200;
  @body pet: Pet;
};
op create(): {
  @statusCode _: 201 | 202;
};
```

#### `@useAuth`

Specify authentication for a whole service or specific methods. See the [documentation in the Http library](https://typespec.io/docs/libraries/http/authentication) for full details.

```typespec
@TypeSpec.Http.useAuth(auth: {} | Union | {}[])
```

##### Target

`Namespace | Interface | Operation`

##### Parameters

| Name | Type                  | Description                                                                                                                                                     |
| ---- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| auth | `{} \| Union \| {}[]` | Authentication configuration. Can be a single security scheme, a union(either option is valid authentication) or a tuple (must use all authentication together) |

##### Examples

```typespec
@service
@useAuth(BasicAuth)
namespace PetStore;
```

---

### Overview (`packages/json-schema/README.md`)

# @typespec/json-schema

TypeSpec library for emitting TypeSpec to JSON Schema and converting JSON Schema to TypeSpec

## Install

```bash
npm install @typespec/json-schema
```

## Usage

Add the `@jsonSchema` decorator to any types or namespaces you want to emit as JSON Schema.

```TypeSpec
import "@typespec/json-schema";

using JsonSchema;

@jsonSchema
namespace Example;

model Car {
  make: string;
  modelName: string;
}
```

## Emitter usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/json-schema
```

2. Via the config

```yaml
emit:
  - "@typespec/json-schema"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/json-schema"
options:
  "@typespec/json-schema":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/json-schema`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `file-type`

**Type:** `"yaml" | "json"`

Serialize the schema as either yaml or json.

### `int64-strategy`

**Type:** `"string" | "number"`

How to handle 64 bit integers on the wire. Options are:

- string: serialize as a string (widely interoperable)
- number: serialize as a number (not widely interoperable)

### `bundleId`

**Type:** `string`

When provided, bundle all the schemas into a single json schema document with schemas under $defs. The provided id is the id of the root document and is also used for the file name.

### `emitAllModels`

**Type:** `boolean`

When true, emit all model declarations to JSON Schema without requiring the @jsonSchema decorator.

### `emitAllRefs`

**Type:** `boolean`

When true, emit all references as json schema files, even if the referenced type does not have the `@jsonSchema` decorator or is not within a namespace with the `@jsonSchema` decorator.

### `seal-object-schemas`

**Type:** `boolean`

**Default:** `false`

If true, then for models emitted as object schemas we default `unevaluatedProperties` to `{ not: {} }`,
if not explicitly specified elsewhere.
Default: `false`

### `polymorphic-models-strategy`

**Type:** `"ignore" | "oneOf" | "anyOf"`

**Default:** `"ignore"`

Strategy for emitting models with the @discriminator decorator:

- ignore: Emit as regular object schema (default). Derived models use allOf to reference their base model.
- oneOf: Emit a oneOf schema with references to all derived models (closed union)
- anyOf: Emit an anyOf schema with references to all derived models (open union)

When using oneOf or anyOf, derived models will inline all properties from their base model
instead of using allOf references. This avoids circular references in the generated schemas,
since the base model references derived models via oneOf/anyOf.

## Decorators

### TypeSpec.JsonSchema

- [`@baseUri`](#@baseuri)
- [`@contains`](#@contains)
- [`@contentEncoding`](#@contentencoding)
- [`@contentMediaType`](#@contentmediatype)
- [`@contentSchema`](#@contentschema)
- [`@extension`](#@extension)
- [`@id`](#@id)
- [`@jsonSchema`](#@jsonschema)
- [`@maxContains`](#@maxcontains)
- [`@maxProperties`](#@maxproperties)
- [`@minContains`](#@mincontains)
- [`@minProperties`](#@minproperties)
- [`@multipleOf`](#@multipleof)
- [`@oneOf`](#@oneof)
- [`@prefixItems`](#@prefixitems)
- [`@uniqueItems`](#@uniqueitems)

#### `@baseUri`

Set the base URI for any schemas emitted from types within this namespace.

```typespec
@TypeSpec.JsonSchema.baseUri(baseUri: valueof string)
```

##### Target

`Namespace`

##### Parameters

| Name    | Type             | Description                                                              |
| ------- | ---------------- | ------------------------------------------------------------------------ |
| baseUri | `valueof string` | The base URI. Schema IDs inside this namespace are relative to this URI. |

#### `@contains`

Specify that the array must contain at least one instance of the provided type.
Use `@minContains` and `@maxContains` to customize how many instances to expect.

```typespec
@TypeSpec.JsonSchema.contains(value: unknown)
```

##### Target

`unknown[] | ModelProperty`

##### Parameters

| Name  | Type      | Description                      |
| ----- | --------- | -------------------------------- |
| value | `unknown` | The type the array must contain. |

#### `@contentEncoding`

Specify the encoding used for the contents of a string.

```typespec
@TypeSpec.JsonSchema.contentEncoding(value: valueof string)
```

##### Target

`string | ModelProperty`

##### Parameters

| Name  | Type             | Description |
| ----- | ---------------- | ----------- |
| value | `valueof string` | <br />      |

#### `@contentMediaType`

Specify the content type of content stored in a string.

```typespec
@TypeSpec.JsonSchema.contentMediaType(value: valueof string)
```

##### Target

`string | ModelProperty`

##### Parameters

| Name  | Type             | Description                           |
| ----- | ---------------- | ------------------------------------- |
| value | `valueof string` | The media type of the string contents |

#### `@contentSchema`

Specify the schema for the contents of a string when interpreted according to the content's
media type and encoding.

```typespec
@TypeSpec.JsonSchema.contentSchema(value: unknown)
```

##### Target

`string | ModelProperty`

##### Parameters

| Name  | Type      | Description                       |
| ----- | --------- | --------------------------------- |
| value | `unknown` | The schema of the string contents |

#### `@extension`

Specify a custom property to add to the emitted schema. This is useful for adding custom keywords
and other vendor-specific extensions. Scalar values need to be specified using `typeof` to be converted to a schema.

For example, `@extension("x-schema", typeof "foo")` will emit a JSON schema value for `x-schema`,
whereas `@extension("x-schema", "foo")` will emit the raw code `"foo"`.

The value will be treated as a raw value if any of the following are true:

- The value is a scalar value (e.g. string, number, boolean, etc.)
- The value is wrapped in the `Json<Data>` template
- The value is provided using the value syntax (e.g. `#{}`, `#[]`)

For example, `@extension("x-schema", { x: "value" })` will emit a JSON schema value for `x-schema`,
whereas `@extension("x-schema", #{x: "value"})` and `@extension("x-schema", Json<{x: "value"}>)`
will emit the raw JSON code `{x: "value"}`.

```typespec
@TypeSpec.JsonSchema.extension(key: valueof string, value: unknown | valueof unknown)
```

##### Target

`unknown`

##### Parameters

| Name  | Type                           | Description                                                   |
| ----- | ------------------------------ | ------------------------------------------------------------- |
| key   | `valueof string`               | The name of the keyword of vendor extension, e.g. `x-custom`. |
| value | `unknown` \| `valueof unknown` | The value of the keyword.                                     |

#### `@id`

Specify the JSON Schema id. If this model or a parent namespace has a base URI,
the provided ID will be relative to that base URI.

By default, the id will be constructed based on the declaration's name.

```typespec
@TypeSpec.JsonSchema.id(id: valueof string)
```

##### Target

`unknown`

##### Parameters

| Name | Type             | Description                                     |
| ---- | ---------------- | ----------------------------------------------- |
| id   | `valueof string` | The id of the JSON schema for this declaration. |

#### `@jsonSchema`

Add to namespaces to emit models within that namespace to JSON schema.
Add to another declaration to emit that declaration to JSON schema.

Optionally, for namespaces, you can provide a baseUri, and for other declarations,
you can provide the id.

```typespec
@TypeSpec.JsonSchema.jsonSchema(baseUri?: valueof string)
```

##### Target

`unknown`

##### Parameters

| Name    | Type             | Description                                         |
| ------- | ---------------- | --------------------------------------------------- |
| baseUri | `valueof string` | Schema IDs are interpreted as relative to this URI. |

#### `@maxContains`

Used in conjunction with the `@contains` decorator,
specifies that the array must contain at most a certain number of the types provided by the `@contains` decorator.

```typespec
@TypeSpec.JsonSchema.maxContains(value: valueof int32)
```

##### Target

`unknown[] | ModelProperty`

##### Parameters

| Name  | Type            | Description                                            |
| ----- | --------------- | ------------------------------------------------------ |
| value | `valueof int32` | The maximum number of instances the array must contain |

#### `@maxProperties`

Specify the maximum number of properties this object can have.

```typespec
@TypeSpec.JsonSchema.maxProperties(value: valueof int32)
```

##### Target

`Record<unknown> | ModelProperty`

##### Parameters

| Name  | Type            | Description                                            |
| ----- | --------------- | ------------------------------------------------------ |
| value | `valueof int32` | The maximum number of properties this object can have. |

#### `@minContains`

Used in conjunction with the `@contains` decorator,
specifies that the array must contain at least a certain number of the types provided by the `@contains` decorator.

```typespec
@TypeSpec.JsonSchema.minContains(value: valueof int32)
```

##### Target

`unknown[] | ModelProperty`

##### Parameters

| Name  | Type            | Description                                            |
| ----- | --------------- | ------------------------------------------------------ |
| value | `valueof int32` | The minimum number of instances the array must contain |

#### `@minProperties`

Specify the minimum number of properties this object can have.

```typespec
@TypeSpec.JsonSchema.minProperties(value: valueof int32)
```

##### Target

`Record<unknown> | ModelProperty`

##### Parameters

| Name  | Type            | Description                                            |
| ----- | --------------- | ------------------------------------------------------ |
| value | `valueof int32` | The minimum number of properties this object can have. |

#### `@multipleOf`

Specify that the numeric type must be a multiple of some numeric value.

```typespec
@TypeSpec.JsonSchema.multipleOf(value: valueof numeric)
```

##### Target

`numeric | ModelProperty`

##### Parameters

| Name  | Type              | Description                                        |
| ----- | ----------------- | -------------------------------------------------- |
| value | `valueof numeric` | The numeric type must be a multiple of this value. |

#### `@oneOf`

Specify that `oneOf` should be used instead of `anyOf` for that union.

```typespec
@TypeSpec.JsonSchema.oneOf
```

##### Target

`Union | ModelProperty`

##### Parameters

None

#### `@prefixItems`

Specify that the target array must begin with the provided types.

```typespec
@TypeSpec.JsonSchema.prefixItems(value: unknown[])
```

##### Target

`unknown[] | ModelProperty`

##### Parameters

| Name  | Type        | Description                                                                 |
| ----- | ----------- | --------------------------------------------------------------------------- |
| value | `unknown[]` | A tuple containing the types that must be present at the start of the array |

#### `@uniqueItems`

Specify that every item in the array must be unique.

```typespec
@TypeSpec.JsonSchema.uniqueItems
```

##### Target

`unknown[] | ModelProperty`

##### Parameters

None

---

### Overview (`packages/library-linter/README.md`)

# TypeSpec Library Linter

## Installation

Install the package as a dev dependency.

```
npm install -D @typespec/library-linter
```

## Usage

Compile your library package. Any errors or warnings will be reported as TypeSpec diagnostics.

```bash
# At the root of your TypeSpec library.
tsp compile . --import @typespec/library-linter
```

## TypeSpec Library Best rules and best practices

| Rule name                  | Description                                                                                                                       |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `missing-namespace`        | Validate that every exported element from the library (models, JS functions, operations, etc.) is in a namespace.                 |
| `missing-signature`        | Validate that every exported JS decorator function has a matching `extern dec` declaration.                                       |
| `missing-documentation`    | Validate that every public declaration and member (properties, enum members, parameters, template parameters) has documentation.  |
| `extraneous-documentation` | Validate that doc comments do not document things that do not exist, such as an unknown `@param` name or an unrecognized doc tag. |

Declarations in a namespace named `Private` and declarations marked `internal` are not part of the
public surface of a library and are excluded from the documentation rules.

---

### Overview (`packages/monarch/README.md`)

# @typespec/monarch

Provide tokenizer for Monarch for use in [monaco-editor](https://github.com/microsoft/monaco-editor).

## Updating

### Updating the tests

You can copy `./temp/monaco-tests.json`(after running the test) into the `src/basic-languages/typespec/typespec.test.ts` test file in the monaco-editor repository.

---

### Overview (`packages/mutator-framework/readme.md`)

# Mutator Framework

**WARNING: THIS PACKAGE IS EXPERIMENTAL AND WILL CHANGE**

This package provides utilities for building mutations of the TypeSpec type
graph. Mutations are modifications to the original type graph that live in a
parallel type graph and contain additional metadata relevant to consumers of
those mutated types.

At a high level you:

- Create mutation classes that control how each TypeSpec type (models,
  properties, unions, scalars, literals, operations, etc.) is traversed and
  transformed.
- Use strongly-typed helper APIs on mutation nodes to mutate into new types or
  traverse to related nodes.
- Instantiate a `MutationEngine` subtype (e.g. `SimpleMutationEngine`) with the
  `Typekit` from the TypeSpec program you want to mutate.

## Key Concepts

### Mutations

Mutations are abstract classes that control how each TypeSpec type kind is
traversed and transformed. They have a protocol based on a static `mutationInfo`
method that returns a unique `mutationKey` for that mutation. If a mutation with
the same key exists, it is reused; otherwise, a new mutation is constructed.

The `mutationInfo` method can also return a `Mutation` directly, useful for
constructing a mutation view "as if" the type graph looked different.

### Mutation Nodes

Mutation nodes represent individual type transformations. They are unique per
`(type, mutationKey)` pair. Connections between nodes are built lazily using
half-edges - mutations call `startXEdge()` methods to create a `MutationHalfEdge`
that gets connected when the target mutation is resolved.

### Key APIs

- `MutationEngine` – orchestrates creation, caching, and traversal of mutations.
- `SimpleMutationEngine` – a convenience engine with Simple\* mutation classes
  that expose a single mutated type per source type.
- `MutationOptions` – lets you parameterize a mutation run and provide a `mutationKey`.
- `MutationHalfEdge` – represents the head-end of a connection; the tail is set when
  the target mutation is resolved.
- `ModelMutation`, `ModelPropertyMutation`, `UnionMutation`, etc. – abstract base
  classes for crafting custom mutations per TypeSpec kind.
- `SimpleModelMutation`, `SimpleModelPropertyMutation`, etc. – concrete implementations
  that expose `mutationNode` and `mutatedType` properties.

## Getting Started

```ts
import type { Model, Program } from "@typespec/compiler";
import { $ } from "@typespec/compiler/typekit";
import {
  SimpleModelMutation,
  SimpleMutationEngine,
  SimpleMutationOptions,
} from "@typespec/mutator-framework";

// Define custom options with a mutationKey
class RenameMutationOptions extends SimpleMutationOptions {
  constructor(readonly suffix: string) {
    super();
  }

  get mutationKey() {
    return this.suffix;
  }
}

// Define a custom mutation that renames models
class RenameModelMutation extends SimpleModelMutation<RenameMutationOptions> {
  mutate() {
    if ("name" in this.sourceType && typeof this.sourceType.name === "string") {
      this.mutationNode.mutate(
        (type) => (type.name = `${this.sourceType.name}${this.options.suffix}`),
      );
    }
    super.mutate();
  }
}

// Create the engine and run mutations
const tk = $(program);
const engine = new SimpleMutationEngine(tk, {
  Model: RenameModelMutation,
});

const options = new RenameMutationOptions("Suf");
const fooMutation = engine.mutate(fooModel, options);
console.log(fooMutation.mutatedType.name); // "FooSuf"
```

## Defining Custom Mutation Options

Options derive from `MutationOptions` (or `SimpleMutationOptions` for simple
mutations). Override the `mutationKey` getter to provide a unique cache key for
your configuration. Mutations are cached per `(type, mutationKey)` pair.

```ts
import { SimpleMutationOptions } from "@typespec/mutator-framework";

class RenameMutationOptions extends SimpleMutationOptions {
  constructor(readonly suffix: string) {
    super();
  }

  get mutationKey() {
    return this.suffix;
  }

  with(options: Partial<{ suffix: string }>) {
    return new RenameMutationOptions(options.suffix ?? this.suffix);
  }
}
```

## Writing Mutation Classes

Mutation classes are abstract classes that derive from the base classes included
in the framework. Override `mutate()` to perform your transformations.

### The `mutationInfo` Protocol

Each mutation class has a static `mutationInfo` method that is called to
determine the unique key for a mutation. The default implementation uses
`options.mutationKey`. Override this to implement context-sensitive mutation
keys based on reference types or other factors:

```ts
class RenameModelBasedOnReferenceMutation extends SimpleModelMutation<SimpleMutationOptions> {
  static mutationInfo(
    engine: SimpleMutationEngine<{ Model: RenameModelBasedOnReferenceMutation }>,
    sourceType: Model,
    referenceTypes: MemberType[],
    options: SimpleMutationOptions,
    halfEdge?: MutationHalfEdge,
    traits?: MutationTraits,
  ): MutationInfo {
    // Different key based on whether this type was reached via a reference
    if (referenceTypes.length === 0) {
      return {
        mutationKey: options.mutationKey + "-no-ref",
        hasReference: false,
        isSynthetic: traits?.isSynthetic,
      };
    }
    return {
      mutationKey: options.mutationKey + "-has-ref",
      hasReference: true,
      isSynthetic: traits?.isSynthetic,
    };
  }

  mutate() {
    if (this.mutationInfo.hasReference) {
      this.mutationNode.mutate((type) => (type.name = `${this.sourceType.name}Reference`));
    }
    super.mutate();
  }
}
```

### Lazy Connections with Half-Edges

Connections between mutations are built lazily. Mutations provide `startXEdge()`
methods that return a `MutationHalfEdge`. Pass this half-edge to `engine.mutate()`
or related methods. When the target mutation is resolved, its mutation node is
connected to the originating mutation's node:

```ts
class SimpleModelMutation extends ModelMutation {
  // Creates a half-edge for connecting to a property mutation
  startPropertyEdge() {
    return new MutationHalfEdge("property", this, (tail) =>
      this.mutationNode.connectProperty(tail.mutationNode),
    );
  }

  mutate() {
    for (const prop of this.sourceType.properties.values()) {
      // Pass the half-edge so the connection is made when resolved
      this.engine.mutate(prop, this.options, this.startPropertyEdge());
    }
  }
}
```

### Replacing Referenced Types

Use `engine.replaceAndMutateReference()` to substitute a type with a different
one while preserving the reference chain. This is useful for wrapping types in
unions or other containers:

```ts
class UnionifyProperty extends SimpleModelPropertyMutation<SimpleMutationOptions> {
  mutate() {
    if (!this.engine.$.union.is(this.sourceType.type)) {
      // Create a union wrapping the original type
      const newUnionType = this.engine.$.union.create({
        name: "DynamicUnion",
        variants: [
          this.engine.$.unionVariant.create({ type: this.sourceType.type }),
          this.engine.$.unionVariant.create({ type: this.engine.$.builtin.string }),
        ],
      });

      // Update the mutation node
      this.mutationNode.mutate((prop) => {
        prop.type = newUnionType;
      });

      // Replace and mutate the reference
      this.type = this.engine.replaceAndMutateReference(
        this.sourceType,
        newUnionType,
        this.options,
        this.startTypeEdge(),
      );
    } else {
      super.mutate();
    }
  }
}
```

### Returning Mutations from `mutationInfo`

The `mutationInfo` method can return a `Mutation` directly instead of a
`MutationInfo` object. This is useful for completely substituting the mutation
for a different one:

```ts
class NullableReferencedModelMutation extends SimpleModelMutation<SimpleMutationOptions> {
  static mutationInfo(
    engine: SimpleMutationEngine<{ Model: NullableReferencedModelMutation }>,
    sourceType: Model,
    referenceTypes: MemberType[],
    options: SimpleMutationOptions,
    halfEdge?: MutationHalfEdge,
    traits?: MutationTraits,
  ) {
    // When accessed via a ModelProperty reference, return a union mutation instead
    if (referenceTypes.length > 0 && referenceTypes[0].kind === "ModelProperty") {
      const nullableUnion = engine.$.union.create({
        name: `${sourceType.name}NullableUnion`,
        variants: [
          engine.$.unionVariant.create({ name: "Value", type: sourceType }),
          engine.$.unionVariant.create({ name: "Null", type: engine.$.intrinsic.null }),
        ],
      });

      // Return a mutation for the union instead
      return engine.replaceAndMutateReference(referenceTypes[0], nullableUnion, options, halfEdge);
    }

    return super.mutationInfo(engine, sourceType, referenceTypes, options, halfEdge, traits);
  }
}
```

Mutation nodes also have a `replace` method. Returning a new mutation from MutationInfo makes the resulting Mutations look "as if" the source type graph were shaped differently. This is useful for doing things like normalizations of the type graph. The structure of the Mutations mimic this new structure. When you `replace` on a mutation node, the Mutation stays the same, but the mutated type graph is changed. This is useful for doing things like renaming things or swapping scalars in situations where you want to see both the source type and the mutated type in order to compare them.

#### Replacing a member's underlying type from `mutationInfo`

When `replaceAndMutateReference` is called from a member's `mutationInfo` (e.g.
a `ModelProperty` or `UnionVariant` overriding `mutationInfo`), the parent's
half-edge expects a member-kind tail (`ModelProperty` / `UnionVariant`) but
`newType` is typically a different kind such as `Model`, `Union`, or `Scalar`.

The engine detects this mismatch (via `MutationHalfEdge.expectedTailKind`,
declared by the built-in `Simple*Mutation` member-yielding edges) and wraps
`newType` in a synthetic member of the expected kind named after the original
reference. The synthetic member's normal mutation flow then mutates `newType`
recursively through its own type edge, so:

- `parentMutation.properties.get("prop")` still returns a `ModelProperty`
  mutation (the synthetic), keeping the parent's slot kind-correct.
- `propMutation.mutatedType.type` points at the mutated `newType`.
- Nested replacements (e.g. an alternate model whose own properties are also
  replaced) compose naturally because each level wraps independently.

If the half-edge does not declare `expectedTailKind` (the default for "type"
edges and any user-defined half-edge), `newType` is mutated directly through
the half-edge — useful for routing alternate types to a separate edge in
custom engines.

## Mutation Caching

Mutations are automatically cached and reused. When you call `engine.mutate()`
with the same type and options (determined by `mutationKey`), you get back the
same mutation instance:

```ts
const barMutation = engine.mutate(Bar, new RenameMutationOptions({ suffix: "X" }));
const fooMutation = engine.mutate(Foo, new RenameMutationOptions({ suffix: "X" }));

// When traversing from Foo to its Bar property, we get the same mutation
expect(fooMutation.properties.get("prop")!.type === barMutation).toBe(true);
```

### Simple Mutation Classes

The `Simple*` mutation classes (e.g., `SimpleModelMutation`, `SimpleModelPropertyMutation`)
are concrete implementations that provide:

- A `mutationNode` property for accessing the underlying mutation node
- A `mutatedType` property for accessing the mutated TypeSpec type
- `startXEdge()` methods for creating half-edges to connected types

## Tips for Building Mutations

- **Always call `super.mutate()`** when you want the default traversal logic after your custom
  changes. Skipping it gives you full control, but you must handle traversal yourself.
- **Use `mutationKey`** to differentiate mutations. Mutations are cached per `(type, mutationKey)` pair.
- **Inspect `referenceTypes`** in `mutationInfo` to learn which `ModelProperty` or `UnionVariant`
  led to the current mutation. This enables context-sensitive mutations.
- **Use half-edges** for lazy connections. Call `startXEdge()` and pass the result to `engine.mutate()`.
- **Override `mutationInfo`** to return different mutation keys or substitute mutations entirely.
- **Use `replaceAndMutateReference`** when you need to substitute a type with a synthetic one.

## Additional Resources

- Browse the files under `packages/mutator-framework/src/mutation` to see the built-in
  mutation implementations.
- The unit tests in `simple-mutation-engine.test.ts` demonstrate end-to-end usage patterns,
  including custom mutation keys, reference replacements, and type substitutions.

---

### Overview (`packages/openapi/README.md`)

# @typespec/openapi

TypeSpec library providing OpenAPI concepts

## Install

```bash
npm install @typespec/openapi
```

## Decorators

### TypeSpec.OpenAPI

- [`@defaultResponse`](#@defaultresponse)
- [`@extension`](#@extension)
- [`@externalDocs`](#@externaldocs)
- [`@info`](#@info)
- [`@operationId`](#@operationid)
- [`@tagMetadata`](#@tagmetadata)

#### `@defaultResponse`

Specify that this model is to be treated as the OpenAPI `default` response.
This differs from the compiler built-in `@error` decorator as this does not necessarily represent an error.

```typespec
@TypeSpec.OpenAPI.defaultResponse
```

##### Target

`Model`

##### Parameters

None

##### Examples

```typespec
@defaultResponse
model PetStoreResponse is object;

op listPets(): Pet[] | PetStoreResponse;
```

#### `@extension`

Attach some custom data to the OpenAPI element generated from this type.

```typespec
@TypeSpec.OpenAPI.extension(key: valueof string, value: valueof unknown)
```

##### Target

`unknown`

##### Parameters

| Name  | Type              | Description      |
| ----- | ----------------- | ---------------- |
| key   | `valueof string`  | Extension key.   |
| value | `valueof unknown` | Extension value. |

##### Examples

```typespec
@extension("x-custom", "My value")
@extension("x-pageable", #{ nextLink: "x-next-link" })
op read(): string;
```

#### `@externalDocs`

Specify the OpenAPI `externalDocs` property for this type.

```typespec
@TypeSpec.OpenAPI.externalDocs(url: valueof string, description?: valueof string)
```

##### Target

`unknown`

##### Parameters

| Name        | Type             | Description             |
| ----------- | ---------------- | ----------------------- |
| url         | `valueof string` | Url to the docs         |
| description | `valueof string` | Description of the docs |

##### Examples

```typespec
@externalDocs(
  "https://example.com/detailed.md",
  "Detailed information on how to use this operation"
)
op listPets(): Pet[];
```

#### `@info`

Specify OpenAPI additional information.
The service `title` is already specified using `@service`.

```typespec
@TypeSpec.OpenAPI.info(additionalInfo: valueof TypeSpec.OpenAPI.AdditionalInfo)
```

##### Target

`Namespace`

##### Parameters

| Name           | Type                                        | Description            |
| -------------- | ------------------------------------------- | ---------------------- |
| additionalInfo | [valueof `AdditionalInfo`](#additionalinfo) | Additional information |

#### `@operationId`

Specify the OpenAPI `operationId` property for this operation.

```typespec
@TypeSpec.OpenAPI.operationId(operationId: valueof string)
```

##### Target

`Operation`

##### Parameters

| Name        | Type             | Description         |
| ----------- | ---------------- | ------------------- |
| operationId | `valueof string` | Operation id value. |

##### Examples

```typespec
@operationId("download")
op read(): string;
```

#### `@tagMetadata`

Specify OpenAPI tag metadata. Can be used in two forms:

- Inline form: specify a single tag by name with optional metadata.
- Array form: specify an ordered list of tags with their metadata in a single decorator call.

```typespec
@TypeSpec.OpenAPI.tagMetadata(name: valueof string | TypeSpec.OpenAPI.TagMetadataWithName[], tagMetadata?: valueof TypeSpec.OpenAPI.TagMetadata)
```

##### Target

`Namespace`

##### Parameters

| Name        | Type                                                       | Description                                                         |
| ----------- | ---------------------------------------------------------- | ------------------------------------------------------------------- |
| name        | `valueof string \| TypeSpec.OpenAPI.TagMetadataWithName[]` | Tag name (inline form) or array of tags with metadata (array form). |
| tagMetadata | [valueof `TagMetadata`](#tagmetadata)                      | Additional information for the tag. Only used in inline form.       |

##### Examples

###### Inline form

```typespec
@service
@tagMetadata(
  "Tag Name",
  #{
    description: "Tag description",
    externalDocs: #{ url: "https://example.com", description: "More info.", `x-custom`: "string" },
    `x-custom`: "string",
  }
)
@tagMetadata("Child Tag", #{ description: "Child tag description", parent: "Tag Name" })
namespace PetStore {

}
```

###### Array form (preserves explicit tag order)

```typespec
@service
@tagMetadata(#[
  #{ name: "First Tag", description: "First tag description" },
  #{ name: "Second Tag", description: "Second tag description" }
])
namespace PetStore {

}
```

---

### Overview (`packages/openapi3/README.md`)

# @typespec/openapi3

TypeSpec library for emitting OpenAPI 3.0 and OpenAPI 3.1 from the TypeSpec REST protocol binding and converting OpenAPI3 to TypeSpec

## Install

```bash
npm install @typespec/openapi3
```

## Emitter usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/openapi3
```

2. Via the config

```yaml
emit:
  - "@typespec/openapi3"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/openapi3"
options:
  "@typespec/openapi3":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/openapi3`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `file-type`

**Type:** `"yaml" | "json" | ("yaml" | "json")[]`

If the content should be serialized as YAML or JSON. Can be a single value or an array to emit multiple formats. Default 'yaml', if not specified infer from the `output-file` extension

**Options:**

- `"yaml" | "json"`
- `("yaml" | "json")[]`

### `output-file`

**Type:** `string`

Name of the output file.
Output file will interpolate the following values:

- service-name: Name of the service
- service-name-if-multiple: Name of the service if multiple
- version: Version of the service if multiple
- file-type: The file type being emitted (json or yaml). Useful when `file-type` is an array.

Default: `{service-name-if-multiple}.{version}.openapi.yaml` or `.json` if `file-type` is `"json"`
When `file-type` is an array: `{service-name-if-multiple}.{version}.openapi.{file-type}`

Example Single service no versioning

- `openapi.yaml`

Example Multiple services no versioning

- `openapi.Org1.Service1.yaml`
- `openapi.Org1.Service2.yaml`

Example Single service with versioning

- `openapi.v1.yaml`
- `openapi.v2.yaml`

Example Multiple service with versioning

- `openapi.Org1.Service1.v1.yaml`
- `openapi.Org1.Service1.v2.yaml`
- `openapi.Org1.Service2.v1.0.yaml`
- `openapi.Org1.Service2.v1.1.yaml`

### `openapi-versions`

**Type:** `"3.0.0" | "3.1.0" | "3.2.0"`

**Default:** `["3.0.0"]`

### `new-line`

**Type:** `"crlf" | "lf"`

**Default:** `"lf"`

Set the newline character for emitting files.

### `omit-unreachable-types`

**Type:** `boolean`

Omit unreachable types.
By default all types declared under the service namespace will be included. With this flag on only types references in an operation will be emitted.

### `include-x-typespec-name`

**Type:** `"inline-only" | "never"`

**Default:** `"never"`

If the generated openapi types should have the `x-typespec-name` extension set with the name of the TypeSpec type that created it.
This extension is meant for debugging and should not be depended on.

### `safeint-strategy`

**Type:** `"double-int" | "int64"`

**Default:** `"int64"`

How to handle safeint type. Options are:

- `double-int`: Will produce `type: integer, format: double-int`
- `int64`: Will produce `type: integer, format: int64`

Default: `int64`

### `seal-object-schemas`

**Type:** `boolean`

**Default:** `false`

If true, then for models emitted as object schemas we default `additionalProperties` to false for
OpenAPI 3.0, and `unevaluatedProperties` to false for OpenAPI 3.1, if not explicitly specified elsewhere.
Default: `false`

### `experimental-parameter-examples`

**Type:** `"data" | "serialized"`

Determines how to emit examples on parameters.
Note: This is an experimental feature and may change in future versions.
See https://spec.openapis.org/oas/v3.0.4.html#style-examples for parameter example serialization rules
See https://github.com/OAI/OpenAPI-Specification/discussions/4622 for discussion on handling parameter examples.

### `operation-id-strategy`

**Type:** `"parent-container" | "fqn" | "explicit-only" | object { kind, separator }`

**Options:**

- `"parent-container" | "fqn" | "explicit-only"` (default: `"parent-container"`)

  Determines how to generate operation IDs when `@operationId` is not used.
  Avaliable options are:

- `parent-container`: Uses the parent namespace and operation name to generate the ID.
- `fqn`: Uses the fully qualified name of the operation to generate the ID.
- `explicit-only`: Only use explicitly defined operation IDs.
- `object { kind, separator }`

| Name        | Type                                             | Default              | Description                                                                                                                                                                                                                                                                                                                                              |
| ----------- | ------------------------------------------------ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `kind`      | `"parent-container" \| "fqn" \| "explicit-only"` | `"parent-container"` | Determines how to generate operation IDs when `@operationId` is not used.<br />Avaliable options are:<br /> - `parent-container`: Uses the parent namespace and operation name to generate the ID.<br /> - `fqn`: Uses the fully qualified name of the operation to generate the ID.<br /> - `explicit-only`: Only use explicitly defined operation IDs. |
| `separator` | `string`                                         |                      | Separator used to join segment in the operation name.                                                                                                                                                                                                                                                                                                    |

### `enum-strategy`

**Type:** `"default" | "annotated"`

**Default:** `"default"`

How to emit TypeSpec enums and unions of literals. Options are:

- `default`: Emit as a single schema using the `enum` keyword.
- `annotated`: Emit as a `oneOf` of `const` subschemas annotated with `title` and `description`
  from each member's/variant's `@summary` and `@doc`. Follows the OpenAPI 3.1.1 annotated enumerations pattern.
  Only supported by OpenAPI 3.1.0 and above; on 3.0.0 the `default` style is used and a warning is reported.

## Decorators

### TypeSpec.OpenAPI

- [`@oneOf`](#@oneof)
- [`@useRef`](#@useref)

#### `@oneOf`

Specify that `oneOf` should be used instead of `anyOf` for that union.

```typespec
@TypeSpec.OpenAPI.oneOf
```

##### Target

`Union | ModelProperty`

##### Parameters

None

#### `@useRef`

Specify an external reference that should be used inside of emitting this type.

```typespec
@TypeSpec.OpenAPI.useRef(ref: valueof string)
```

##### Target

`Model | ModelProperty`

##### Parameters

| Name | Type             | Description                                                          |
| ---- | ---------------- | -------------------------------------------------------------------- |
| ref  | `valueof string` | External reference(e.g. "../../common.json#/components/schemas/Foo") |

---

### Overview (`packages/playground-website/README.md`)

# TypeSpec Playground Website

A self contained website for the TypeSpec Playground.

## Use

- `npm start` to start in dev mode
- `npm run preview` to build and preview prod mode
- `npm run build` to build for production

## Configuration

To change the default configuration add a `.env.local` file in the root of this package.

The following environment variables are available:

```.env
# Bundle and use local version of TypeSpec libraries
VITE_USE_LOCAL_LIBRARIES=true
```

---

### Overview (`packages/playground/README.md`)

# TypeSpec Playground

Contains react components for the TypeSpec playground.

It can be used as a standalone custom playground with your own libraries or components can be used individually to customize the UI as you see fit.

## Usage

### Standalone

The stanalone playground provides some vite helpers to make it easy to get started.

In `vite.config.ts`:

```ts
import { definePlaygroundViteConfig } from "@typespec/playground/vite";

const config = definePlaygroundViteConfig({
  defaultEmitter: "@typespec/openapi3",
  libraries: [
    "@typespec/compiler",
    "@typespec/http",
    "@typespec/openapi3",

    // Add any other libraries here. Make sure those libraries are also dependencies of that package.
  ],
  samples: {
    "My sample": {
      filename: "samples/my.tsp",
      preferredEmitter: "@typespec/openapi3",
    },
  },
  links: {
    documentationUrl: "<link to your website>",
  },
});

export default config;
```

In `src/main.tsx`:

```tsx
import { registerMonacoDefaultWorkersForVite } from "@typespec/playground";
import PlaygroundManifest from "@typespec/playground/manifest";
import { renderReactPlayground } from "@typespec/playground/react";
import { SwaggerUIViewer } from "@typespec/playground/react/viewers";

// Import styles
import "@typespec/playground/styles.css";

registerMonacoDefaultWorkersForVite();

await renderReactPlayground({
  ...PlaygroundManifest,
  emitterViewers: {
    "@typespec/openapi3": [SwaggerUIViewer],
  },
});
```

### Individual components

Playground react components can be used individually. For the TypeSpec compiler to be working correctly, the following conditions need to be met:

- The libraries **MUST** be loaded and registered
- The libraries **MUST** be importable by their name this means an import map must be setup. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
- The libraries **MUST** have been bundled using `@typespec/bundler`

---

### Overview (`packages/prettier-plugin-typespec/README.md`)

# Prettier Plugin for TypeSpec

## Requirements

- **Using Node 14 and above**
- For use in **VS Code**, use version `VS Code 1.56` and above.

## Getting Started

```bash
npm install --save-dev prettier @typespec/prettier-plugin-typespec
```

You can now call prettier

```bash
./node_modules/.bin/prettier --write '**/*.tsp'
```

---

### Overview (`packages/protobuf/README.md`)

# @typespec/protobuf

TypeSpec library and emitter for Protobuf (gRPC)

## Install

```bash
npm install @typespec/protobuf
```

## Emitter usage

1. Via the command line

```bash
tsp compile . --emit=@typespec/protobuf
```

2. Via the config

```yaml
emit:
  - "@typespec/protobuf"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/protobuf"
options:
  "@typespec/protobuf":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/protobuf`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `noEmit`

**Type:** `boolean`

If set to `true`, this emitter will not write any files. It will still validate the TypeSpec sources to ensure they are compatible with Protobuf, but the files will simply not be written to the output directory.

### `omit-unreachable-types`

**Type:** `boolean`

By default, the emitter will create `message` declarations for any models in a namespace decorated with `@package` that have an `@field` decorator on every property. If this option is set to true, this behavior will be disabled, and only messages that are explicitly decorated with `@message` or that are reachable from a service operation will be emitted.

### `enum-value-prefix`

**Type:** `"none" | "enum-name"`

**Default:** `"none"`

When set to `enum-name`, enum values are prefixed with the enum name in UPPER_SNAKE_CASE. Already-prefixed names are preserved. By default (`none`), member names are emitted unchanged. This option only changes names; explicit integer values and a first member set to zero are still required.

## Decorators

### TypeSpec.Protobuf

- [`@field`](#@field)
- [`@message`](#@message)
- [`@package`](#@package)
- [`@reserve`](#@reserve)
- [`@service`](#@service)
- [`@stream`](#@stream)

#### `@field`

Defines the field index of a model property or union variant for conversion to a Protobuf
message.

When applied to the variants of a named union, the union can be used as the type of a message field:

- If the model property has no `@field` decorator, the union is emitted inline as a `oneof` named after the
  property, and the variant field indices share the field index space of the containing message. The property
  must be optional.
- If the model property has a `@field` decorator, the union is emitted as a wrapper message (named after the
  union) that contains a `oneof value`, and the variant field indices belong to the wrapper message.

Union variants used in a `oneof` cannot be arrays or maps.

The field index of a Protobuf message must:

- fall between 1 and 2<sup>29</sup> - 1, inclusive.
- not fall within the implementation reserved range of 19000 to 19999, inclusive.
- not fall within any range that was [marked reserved](#%40TypeSpec.Protobuf.reserve).
- not be used by any other field of the same message, including members of a `oneof`.

#### API Compatibility Note

Fields are accessed by index, so changing the index of a field is an API breaking change.

#### Encoding

Field indices between 1 and 15 are encoded using a single byte, while field indices from 16 through 2047 require two
bytes, so those indices between 1 and 15 should be preferred and reserved for elements that are frequently or always
set in the message. See the [Protobuf binary format](https://protobuf.dev/programming-guides/encoding/).

```typespec
@TypeSpec.Protobuf.field(index: valueof uint32)
```

##### Target

`ModelProperty | UnionVariant`

##### Parameters

| Name  | Type             | Description                          |
| ----- | ---------------- | ------------------------------------ |
| index | `valueof uint32` | The whole-number index of the field. |

##### Examples

```typespec
model ExampleMessage {
  @field(1)
  test: string;
}
```

```typespec
union Payment {
  @field(10) card: CardPayment,
  @field(11) bank_transfer: BankTransfer,
}

model Order {
  @field(1) id: string;

  // Emitted inline as `oneof payment { CardPayment card = 10; BankTransfer bank_transfer = 11; }`
  payment?: Payment;
}
```

#### `@message`

Declares that a model is a Protobuf message.

Messages can be detected automatically if either of the following two conditions are met:

- The model has a `@field` annotation on all of its properties.
- The model is referenced by any service operation.

This decorator will force the emitter to check and emit a model. A named union annotated with this decorator is
emitted as a wrapper message containing a `oneof value`.

```typespec
@TypeSpec.Protobuf.message
```

##### Target

`{}`

##### Parameters

None

#### `@package`

Declares that a TypeSpec namespace constitutes a Protobuf package. The contents of the namespace will be emitted to a
single Protobuf file.

```typespec
@TypeSpec.Protobuf.package(details?: TypeSpec.Protobuf.PackageDetails)
```

##### Target

`Namespace`

##### Parameters

| Name    | Type                                | Description                         |
| ------- | ----------------------------------- | ----------------------------------- |
| details | [`PackageDetails`](#packagedetails) | the optional details of the package |

#### `@reserve`

Reserve a field index, range, or name. If a field definition collides with a reservation, the emitter will produce
an error.

This decorator accepts multiple reservations. Each reservation is one of the following:

- a `string`, in which case the reservation refers to a field name.
- a `uint32`, in which case the reservation refers to a field index.
- a tuple `[uint32, uint32]`, in which case the reservation refers to a field range that is _inclusive_ of both ends.

Unlike in Protobuf, where field name and index reservations must be separated, you can mix string and numeric field
reservations in a single `@reserve` call in TypeSpec.

#### API Compatibility Note

Field reservations prevent users of your Protobuf specification from using the given field names or indices. This can
be useful if a field is removed, as it will further prevent adding a new, incompatible field and will prevent users
from utilizing the field index at runtime in a way that may break compatibility with users of older specifications.

See _[Protobuf Language Guide - Reserved Fields](https://protobuf.dev/programming-guides/proto3/#reserved)_ for more
information.

```typespec
@TypeSpec.Protobuf.reserve(...reservations: valueof string | [uint32, uint32] | uint32[])
```

##### Target

`{}`

##### Parameters

| Name         | Type                                             | Description                  |
| ------------ | ------------------------------------------------ | ---------------------------- |
| reservations | `valueof string \| [uint32, uint32] \| uint32[]` | a list of field reservations |

##### Examples

```typespec
// Reserve the fields 8-15 inclusive, 100, and the field name "test" within a model.
@reserve([8, 15], 100, "test")
model Example {
  // ...
}
```

#### `@service`

Declares that a TypeSpec interface constitutes a Protobuf service. The contents of the interface will be converted to
a `service` declaration in the resulting Protobuf file.

```typespec
@TypeSpec.Protobuf.service
```

##### Target

`Interface`

##### Parameters

None

#### `@stream`

Set the streaming mode of an operation. See [StreamMode](./data-types#TypeSpec.Protobuf.StreamMode) for more information.

```typespec
@TypeSpec.Protobuf.stream(mode: TypeSpec.Protobuf.StreamMode)
```

##### Target

`Operation`

##### Parameters

| Name | Type                        | Description                                    |
| ---- | --------------------------- | ---------------------------------------------- |
| mode | [`StreamMode`](#streammode) | The streaming mode to apply to this operation. |

##### Examples

```typespec
@stream(StreamMode.Out)
op logs(...LogsRequest): LogEvent;
```

```typespec
@stream(StreamMode.Duplex)
op connectToMessageService(...Message): Message;
```

---

### Overview (`packages/react-components/README.md`)

# Set of components that are used in different UI packages of TypeSpec

---

### Overview (`packages/rest/README.md`)

# @typespec/rest

TypeSpec REST protocol binding

## Install

```bash
npm install @typespec/rest
```

## Decorators

### TypeSpec.Rest

- [`@action`](#@action)
- [`@actionSeparator`](#@actionseparator)
- [`@autoRoute`](#@autoroute)
- [`@collectionAction`](#@collectionaction)
- [`@copyResourceKeyParameters`](#@copyresourcekeyparameters)
- [`@createsOrReplacesResource`](#@createsorreplacesresource)
- [`@createsOrUpdatesResource`](#@createsorupdatesresource)
- [`@createsResource`](#@createsresource)
- [`@deletesResource`](#@deletesresource)
- [`@listsResource`](#@listsresource)
- [`@parentResource`](#@parentresource)
- [`@readsResource`](#@readsresource)
- [`@resource`](#@resource)
- [`@segment`](#@segment)
- [`@segmentOf`](#@segmentof)
- [`@updatesResource`](#@updatesresource)

#### `@action`

Specify this operation is an action. (Scoped to a resource item /pets/{petId}/my-action)

```typespec
@TypeSpec.Rest.action(name?: valueof string)
```

##### Target

`Operation`

##### Parameters

| Name | Type             | Description                                                                   |
| ---- | ---------------- | ----------------------------------------------------------------------------- |
| name | `valueof string` | Name of the action. If not specified, the name of the operation will be used. |

#### `@actionSeparator`

Defines the separator string that is inserted before the action name in auto-generated routes for actions.

When applied to a namespace, the separator applies to all action operations in that namespace and its sub-namespaces.
When applied to an interface, the separator applies to all action operations in that interface and overrides any namespace-level separator.
When applied to an operation, the separator applies only to that operation and overrides any interface or namespace-level separator.

```typespec
@TypeSpec.Rest.actionSeparator(seperator: valueof "/" | ":" | "/:")
```

##### Target

`Operation | Interface | Namespace`

##### Parameters

| Name      | Type                         | Description                                                      |
| --------- | ---------------------------- | ---------------------------------------------------------------- |
| seperator | `valueof "/" \| ":" \| "/:"` | Seperator seperating the action segment from the rest of the url |

#### `@autoRoute`

This interface or operation should resolve its route automatically. To be used with resource types where the route segments area defined on the models.

```typespec
@TypeSpec.Rest.autoRoute
```

##### Target

`Interface | Operation`

##### Parameters

None

##### Examples

```typespec
@autoRoute
interface Pets {
  get(@segment("pets") @path id: string): void; //-> route: /pets/{id}
}
```

#### `@collectionAction`

Specify this operation is a collection action. (Scopped to a resource, /pets/my-action)

```typespec
@TypeSpec.Rest.collectionAction(resourceType: Model, name?: valueof string)
```

##### Target

`Operation`

##### Parameters

| Name         | Type             | Description                                                                   |
| ------------ | ---------------- | ----------------------------------------------------------------------------- |
| resourceType | `Model`          | Resource marked with `@resource`                                              |
| name         | `valueof string` | Name of the action. If not specified, the name of the operation will be used. |

#### `@copyResourceKeyParameters`

Copy the resource key parameters on the model

```typespec
@TypeSpec.Rest.copyResourceKeyParameters(filter?: valueof string)
```

##### Target

`Model`

##### Parameters

| Name   | Type             | Description                           |
| ------ | ---------------- | ------------------------------------- |
| filter | `valueof string` | Filter to exclude certain properties. |

#### `@createsOrReplacesResource`

Specify that this is a CreateOrReplace operation for a given resource.

```typespec
@TypeSpec.Rest.createsOrReplacesResource(resourceType: Model)
```

##### Target

`Operation`

##### Parameters

| Name         | Type    | Description                      |
| ------------ | ------- | -------------------------------- |
| resourceType | `Model` | Resource marked with `@resource` |

#### `@createsOrUpdatesResource`

Specify that this is a CreatesOrUpdate operation for a given resource.

```typespec
@TypeSpec.Rest.createsOrUpdatesResource(resourceType: Model)
```

##### Target

`Operation`

##### Parameters

| Name         | Type    | Description                      |
| ------------ | ------- | -------------------------------- |
| resourceType | `Model` | Resource marked with `@resource` |

#### `@createsResource`

Specify that this is a Create operation for a given resource.

```typespec
@TypeSpec.Rest.createsResource(resourceType: Model)
```

##### Target

`Operation`

##### Parameters

| Name         | Type    | Description                      |
| ------------ | ------- | -------------------------------- |
| resourceType | `Model` | Resource marked with `@resource` |

#### `@deletesResource`

Specify that this is a Delete operation for a given resource.

```typespec
@TypeSpec.Rest.deletesResource(resourceType: Model)
```

##### Target

`Operation`

##### Parameters

| Name         | Type    | Description                      |
| ------------ | ------- | -------------------------------- |
| resourceType | `Model` | Resource marked with `@resource` |

#### `@listsResource`

Specify that this is a List operation for a given resource.

```typespec
@TypeSpec.Rest.listsResource(resourceType: Model)
```

##### Target

`Operation`

##### Parameters

| Name         | Type    | Description                      |
| ------------ | ------- | -------------------------------- |
| resourceType | `Model` | Resource marked with `@resource` |

#### `@parentResource`

Mark model as a child of the given parent resource.

```typespec
@TypeSpec.Rest.parentResource(parent: Model)
```

##### Target

`Model`

##### Parameters

| Name   | Type    | Description   |
| ------ | ------- | ------------- |
| parent | `Model` | Parent model. |

#### `@readsResource`

Specify that this is a Read operation for a given resource.

```typespec
@TypeSpec.Rest.readsResource(resourceType: Model)
```

##### Target

`Operation`

##### Parameters

| Name         | Type    | Description                      |
| ------------ | ------- | -------------------------------- |
| resourceType | `Model` | Resource marked with `@resource` |

#### `@resource`

Mark this model as a resource type with a name.

```typespec
@TypeSpec.Rest.resource(collectionName: valueof string)
```

##### Target

`Model`

##### Parameters

| Name           | Type             | Description            |
| -------------- | ---------------- | ---------------------- |
| collectionName | `valueof string` | type's collection name |

#### `@segment`

Defines the preceding path segment for a `@path` parameter in auto-generated routes.

```typespec
@TypeSpec.Rest.segment(name: valueof string)
```

##### Target

`Model | ModelProperty | Operation`

##### Parameters

| Name | Type             | Description                                                                                    |
| ---- | ---------------- | ---------------------------------------------------------------------------------------------- |
| name | `valueof string` | Segment that will be inserted into the operation route before the path parameter's name field. |

##### Examples

```typespec
@autoRoute
interface Pets {
  get(@segment("pets") @path id: string): void; //-> route: /pets/{id}
}
```

#### `@segmentOf`

Returns the URL segment of a given model if it has `@segment` and `@key` decorator.

```typespec
@TypeSpec.Rest.segmentOf(type: Model)
```

##### Target

`Operation`

##### Parameters

| Name | Type    | Description  |
| ---- | ------- | ------------ |
| type | `Model` | Target model |

#### `@updatesResource`

Specify that this is a Update operation for a given resource.

```typespec
@TypeSpec.Rest.updatesResource(resourceType: Model)
```

##### Target

`Operation`

##### Parameters

| Name         | Type    | Description                      |
| ------------ | ------- | -------------------------------- |
| resourceType | `Model` | Resource marked with `@resource` |

---

### Overview (`packages/samples/README.md`)

# TypeSpec Samples

This project has a collection of samples used to demonstrate and test various TypeSpec features.

It is not published as an npm package.

Samples should teach a distinct TypeSpec concept or realistic workflow. Narrow protocol test
cases belong in the relevant package test suite instead of this collection.

Each sample directory has a `sample-config.yaml` containing a unique `title` and a
`description`. Set `playground: false` for samples that require multiple files or are not suitable
for the playground. A directory config uses `directory: true` and can provide a gallery `label`,
`danger`, or an inherited `playground: false`.

The TypeSpec playground is generated from the eligible samples in this package. A playground
sample must contain a single `main.tsp`; its nearest `tspconfig.yaml` selects the preferred emitter
and linter rule set, including inherited configuration.

```bash
npm run test    # Check Samples match snapshots
npm run test:ci # run test same as CI

npm run test:regen -- -g "<sample-name>" # Regen of this name

npm run regen-samples # Regen all samples.
```

---

### Overview (`packages/spec-dashboard/README.md`)

# Spector Dashboard

## Coverage overview groups

Use `groupEmitters` to combine emitters into named overview cards:

```tsx
<Dashboard
  coverageSummaries={coverageSummaries}
  showOverview
  groupEmitters={[
    {
      name: "C#",
      emitters: ["@azure-typespec/http-client-csharp", "@azure-typespec/http-client-csharp-mgmt"],
    },
  ]}
  emitterDisplayNames={{
    "@azure-typespec/http-client-csharp": "C# (Data plane)",
    "@azure-typespec/http-client-csharp-mgmt": "C# (Management plane)",
  }}
/>
```

Each card shows the union of its emitters' coverage, with individual percentages underneath.
A scenario counts once per table and is covered if any member reports `pass`, `not-applicable`,
or `not-supported`. Two emitters each covering 50 of 100 scenarios, with 25 shared successes,
produce **75%** combined coverage. Counts follow the selected tier and use each table's reports;
equally named scenarios in different tables/spec sets remain separate.

Groups and emitter rows follow the configured order; ungrouped emitters keep separate cards
afterward. `emitterDisplayNames` controls row and table labels without affecting grouping.
These options are also available on `DashboardFromAzureStorage`'s `options` and do not change
table columns or report loading.

## Dev

```bash
npm run start
# or
npm run dev
```

## Show the test generator

Add `?showtest=true` query parameter to url http://localhost:5173/?showtest=true

---

### Overview (`packages/spec/README.md`)

# TypeSpec Specification Source

This project builds the [TypeSpec Language Specification](../../docs/spec.html).

It is not published as an npm package.

---

### Overview (`packages/spector/README.md`)

# Spector

Spector is a tool and typespec library used to describe spec for various protocols and running mock server and mock client based on these specs and some mock apis data.

## Scenario project features

Scenario compilation and mock API validation honor compiler feature flags in the scenario's project configuration. For example, place this `tspconfig.yaml` next to a scenario using `union extends`:

```yaml
kind: project
features:
  - union-extends
```

Configuration errors are reported alongside TypeSpec diagnostics. Spector continues to compile without emitting code and treats compiler warnings as errors; emitter and linter settings do not change its validation behavior.

## Commands

### `serve`

```bash
tsp serve ./path/to/specs/
tsp serve ./path/to/specs/ --port 3000
```

### `server start` and `server stop`

Start the server and stop the server in a separate process.

```bash
tsp server start ./path/to/specs/
... run tests ...
tsp server stop
```

### `knock`

```bash
tsp knock ./path/to/specs/
tsp knock ./path/to/specs/ --baseUrl http://localhost:3000
tsp knock ./path/to/specs/ --filter "payload/multipart/**/*"
```

### Options:

| Option      | Description                              | Default                 |
| ----------- | ---------------------------------------- | ----------------------- |
| `--baseUrl` | Base url for the server                  | `http://localhost:3000` |
| `--filter`  | Filters for which scenarios to run(glob) |                         |

---

### Overview (`packages/sse/README.md`)

# @typespec/sse

TypeSpec library providing server sent events bindings

## Install

```bash
npm install @typespec/sse
```

## Decorators

### TypeSpec.SSE

- [`@terminalEvent`](#@terminalevent)

#### `@terminalEvent`

Indicates that the presence of this event is a terminal event,
and the client should disconnect from the server.

```typespec
@TypeSpec.SSE.terminalEvent
```

##### Target

`UnionVariant`

##### Parameters

None

---

### Overview (`packages/standalone/README.md`)

# TypeSpec CLI Standalone Package

This package contains the logic for building and bundling the TypeSpec CLI as a standalone executable.

It requires Node.js 25.5+ to build: the executable is produced in one step with
[`node --build-sea`](https://nodejs.org/api/single-executable-applications.html). This package only
targets the latest Node.js — supporting older versions is a non-goal. The end user runs the
self-contained executable and does not need any Node.js version installed.

## Bundled compiler

The executable ships with a **pinned** `@typespec/compiler` (the version built alongside it)
embedded directly inside the single-executable. The compiler's `tsp init` templates are embedded as
executable assets and served from memory, so running commands such as `tsp init` outside of an
installed project needs **no network access, no package manager, and no files written to disk**.

The standard library is **not** bundled. The bundled compiler is a bootstrapper: it runs `init`,
`--version`, `--help`, and `format` offline, while `compile` always uses a project-local
`@typespec/compiler`. Running `tsp compile` with no local compiler installed fails with guidance to
run `tsp install` / `tsp init` first.

Compiler resolution at runtime:

1. `--server <path>` / `TYPESPEC_COMPILER_PATH` — used if provided.
2. A `@typespec/compiler` resolvable from the current working directory (a project-local install)
   always takes precedence over the bundled one.
3. Otherwise the pinned compiler bundled into the executable is used.

To upgrade the compiler used outside of a project, install a newer executable; there is no runtime
self-update.

## Implementation notes: long-term design vs. temporary workarounds

**Long-term design** (inherent to shipping a self-contained executable):

- The bundled compiler is a **bootstrapper**: it bundles only the `tsp init` templates, not the
  standard library. `src/cli.ts` (`requireLocalCompilerForCompile`) fails fast with actionable
  guidance if `compile` is run with no project-local compiler installed.
- The `tsp init` templates are embedded as a single-executable asset (a map of template-relative
  path to file contents). `compiler-entry.ts` builds an `InMemoryTemplateSource` from that asset and
  passes it to the CLI via `runTypeSpecCli({ coreTemplateSource })` (from
  `@typespec/compiler/internals/standalone`), so `init` serves templates fully from memory while
  everything else uses the real `NodeHost`. No global state is shared between the CJS and ESM
  entrypoints, and the compiler's host contract (`getExecutionRoot`) is left untouched.
- In-memory module serving via `module.registerHooks` (`ensureHooks`/`serveFromMemory` in
  `src/module-loader.ts`): SEA assets are strings in memory, so hooks map synthetic URLs to those
  sources.
- The compiler is bundled as a separate ESM asset because it uses top-level `await`, which a
  CommonJS single-executable main cannot.

**Temporary workarounds** (remove when the linked upstream issue is fixed — each is tagged with a
`WORKAROUND(...)` comment in the code):

| Where                                                                     | Issue                                                            | What / removal                                                                                                                                     |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src/import-workaround.ts` (the `createRequire` bridge, `importExternal`) | [nodejs/node#62726](https://github.com/nodejs/node/issues/62726) | A SEA main can only import _builtin_ modules. Once fixed, delete this file and replace `importExternal(specifier)` calls with `import(specifier)`. |

---

### Overview (`packages/streams/README.md`)

# @typespec/streams

TypeSpec library providing stream bindings

## Install

```bash
npm install @typespec/streams
```

## Decorators

### TypeSpec.Streams

- [`@streamOf`](#@streamof)

#### `@streamOf`

Specify that a model represents a stream protocol type whose data is described
by `Type`.

```typespec
@TypeSpec.Streams.streamOf(type: unknown)
```

##### Target

`Model`

##### Parameters

| Name | Type      | Description                                             |
| ---- | --------- | ------------------------------------------------------- |
| type | `unknown` | The type that models the underlying data of the stream. |

##### Examples

```typespec
model Message {
  id: string;
  text: string;
}

@streamOf(Message)
model Response {
  @body body: string;
}
```

---

### Overview (`packages/tmlanguage-generator/README.md`)

# TMLanguage Generator

This package provides a helper library for authoring TextMate grammars using TypeScript.

## Usage Examples

- [TypeSpec](https://github.com/microsoft/typespec/blob/main/packages/compiler/src/server/tmlanguage.ts)
- [Bicep](https://github.com/Azure/bicep/blob/main/src/textmate/src/bicep.ts)

---

### Overview (`packages/tspd/README.md`)

# @typespec/tspd

**This library is experimental and will most likely significantly change in future versions.**

TypeSpec tspd is a tool to help you build TypeSpec libraries and emitters. It provide the ability to

- Generate decorator signatures and type checks
- Generate documentation for library types and emitter options

## Usage

```bash
tspd --enable-experimental gen-extern-signature
```

```bash
tspd --enable-experimental doc . --output-dir ./docs/
```

## Sub path exports

`gen-extern-signature` generates signatures for every entry of the `exports` field in `package.json` that defines a `typespec` condition.

Each export is compiled on its own and a decorator or function is attributed to the first export that reaches the file declaring it. This means entities declared in the root entrypoint stay on the root even when a sub path entrypoint imports it back.

Signatures for the root export(`.`) are written to `generated-defs/`, signatures for a sub path are written to a matching directory and import `$decorators`/`$functions` from that same sub path:

```
generated-defs/MyLib.ts                  <- from `.`,          imports from "my-lib"
generated-defs/streams/MyLib.Streams.ts  <- from `./streams`,  imports from "my-lib/streams"
```

For this to work the sub path must expose its own JS module (an `import` or `default` condition) exporting the `$decorators` of the decorators it declares, and its TypeSpec entrypoint must import that JS module.

---

### Overview (`packages/typespec-vs/README.md`)

# TypeSpec Language Support for Visual Studio

[Repository](https://github.com/microsoft/typespec) | [Documentation](https://typespec.io/docs) | [Issues](https://github.com/microsoft/typespec/issues) | [Samples](https://github.com/microsoft/typespec/tree/main/packages/samples/specs)

This provides provides [TypeSpec](https://github.com/microsoft/typespec) language support for Visual Studio.

## Features

- Live diagnostic reporting
- Syntax highlighting
- Code completion
- Code folding
- Formatting
- Hover info
- Rename refactoring
- Go to definition

## Configure TypeSpec Visual Studio Extension

1. Create a file `.vs/VSWorkspaceSettings.json` at the root of the project.
2. Add configuration as key value pair in this file. Example:

```json
{
  "typespec.tsp-server.path": "${workspaceFolder}/my-nested-project/node_modules/@typespec/compiler"
}
```

TypeSpec wil interpolate a few variables using this pattern `${<name>}`. For example `${workspaceFolder}`.

Available variables:

- `workspaceFolder`: Correspond to the root of your Visual Studio workspace.

---

### Overview (`packages/typespec-vscode/README.md`)

# TypeSpec Extension in Visual Studio Code

[Repository](https://github.com/microsoft/typespec) | [Documentation](https://typespec.io/docs) | [Issues](https://github.com/microsoft/typespec/issues) | [Samples](https://github.com/microsoft/typespec/tree/main/packages/samples/specs)

The TypeSpec extension for Visual Studio Code enhances the development of TypeSpec by leveraging VS Code's powerful features. It provides:

- IntelliSense and syntax highlighting
- Code autocompletion and formatting
- Live diagnostics and quick fixes
- Refactoring tools (rename, go-to definition, etc.)
- Seamless project setup and emitter configuration <_new_>
- Import TypeSpec from existing OpenAPI 3 definitions <_new_>
- Emit code from TypeSpec <_new_>
- Preview API documentation <_new_>

## Prerequisites

Before using the TypeSpec extension, install [Node.js](https://nodejs.org/en/download/) and verify npm is available:

```sh
npm --version
```

Install the TypeSpec CLI:

```sh
npm install @typespec/compiler
```

Other necessary installations will be prompted within the extension as needed.

## Features

### Write TypeSpec

- **IntelliSense & Auto-completion**: Code faster with smart suggestions.
- **Code Formatting & Folding**: Keep your code clean and organized with built-in formatting and folding support.
- **Syntax Highlighting**: Clear and readable TypeSpec syntax.
- **Live Diagnostics**: Get real-time feedback on code issues.
- **Quick Fixes & Refactoring**: Rename, go-to definition, and format with ease.
- **Hover Info**: Get detailed information about TypeSpec elements by hovering over them.



### Create TypeSpec Project

**Create TypeSpec Project**: Easily initialize a new TypeSpec project based on a template, ensuring a structured and ready-to-use setup.



### Emit Code from TypeSpec

The extension allows emitting various outputs from TypeSpec:

- **OpenAPI Specification**
- **Server SDKs**: Emit server stubs for different back-end frameworks.
- **Client SDKs**: Emit client code for multiple languages, including:
  - .NET (C#)
  - Python
  - Java
  - JavaScript/TypeScript

The action appears in the context menu on a tsp file. Or invoke `TypeSpec: Emit From TypeSpec` to emit needed outputs:



### Import TypeSpec from OpenAPI 3

The extension supports to import TypeSpec from OpenAPI 3. Invoke `TypeSpec: Import TypeSpec from OpenAPI 3` to begin importing.



### Preview API Documentation

The extension allows to preview API documentation. The action appears in the context menu on a tsp file. Or invoke `TypeSpec: Preview API Documentation` to visualize your API definitions.



## Commands

The extension provides the following commands:

| **Command**                                        | **Description**                                                     |
| -------------------------------------------------- | ------------------------------------------------------------------- |
| `TypeSpec: Create TypeSpec Project`                | Scaffold a new TypeSpec project.                                    |
| `TypeSpec: Install TypeSpec Compiler/CLI globally` | Install the TypeSpec Compiler/CLI globally.                         |
| `TypeSpec: Emit from TypeSpec`                     | Compile and generate from TypeSpec files into the specified output. |
| `TypeSpec: Restart TypeSpec Server`                | Restart the TypeSpec language server.                               |
| `TypeSpec: Show Output Channel`                    | Open the TypeSpec output channel to view logs.                      |
| `TypeSpec: Preview API Documentation`              | Preview API documentation generated from TypeSpec in the workspace. |
| `TypeSpec: Import TypeSpec from OpenAPI 3`         | Import TypeSpec from existing OpenAPI 3 definitions                 |

## Configuration

TypeSpec will interpolate a few variables using this pattern `${<name>}`. For example `${workspaceFolder}`.

Available variables:

- `workspaceFolder`: Correspond to the root of your Visual Studio workspace.

### `typespec.tsp-server.path`: Configure the server path

There are cases where the TypeSpec project is located in a subfolder. In such cases, the TypeSpec extension is not able to find the tsp compiler automatically and needs a little guidance.
This setting provides the ability to configure where the tsp compiler is located.

```json
{
  "typespec.tsp-server.path": "${workspaceFolder}/my-nested-project/node_modules/@typespec/compiler"
}
```

## Telemetry

The TypeSpec Extension for Visual Studio Code collects usage data and sends it to Microsoft to help improve our products and services. Read our [privacy statement](https://privacy.microsoft.com/privacystatement) to learn more. This extension respects the `telemetry.telemetryLevel` setting which you can find more information in the [FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting) and [Telemetry Data](https://aka.ms/typespec/vscexdata).

---

### Overview (`packages/versioning/README.md`)

# @typespec/versioning

TypeSpec library for declaring and emitting versioned APIs

## Install

```bash
npm install @typespec/versioning
```

## Usage

### Consuming versioning library from an emitter

#### Get the service representation at a given version

Versioning library works with projection to project the service at a given version.

```ts
// Get a list of all the different version of the service and the projections
const projections = buildVersionProjections(program, serviceNamespace);

for (const projection of projections) {
  const projectedProgram = projectProgram(program, projection.projections);
  // projectedProgram now contains the representation of the service at the given version.
}
```

#### Get list of versions and version dependency across namespaces

Versioning library works with projection to project the service at a given version.

```ts
const versions = resolveVersions(program, serviceNamespace);
// versions now contain a list of all the version of the service namespace and what version should all the other dependencies namespace use.
```

#### Consume versioning manually

If the emitter needs to have the whole picture of the service evolution across the version then using the decorator accessor will provide the metadata for each type:

- `getAddedOn`
- `getRemovedOn`
- `getRenamedFromVersion`
- `getMadeOptionalOn`

## Decorators

### TypeSpec.Versioning

- [`@added`](#@added)
- [`@madeOptional`](#@madeoptional)
- [`@madeRequired`](#@maderequired)
- [`@removed`](#@removed)
- [`@renamedFrom`](#@renamedfrom)
- [`@returnTypeChangedFrom`](#@returntypechangedfrom)
- [`@typeChangedFrom`](#@typechangedfrom)
- [`@useDependency`](#@usedependency)
- [`@versioned`](#@versioned)

#### `@added`

Identifies when the target was added.

```typespec
@TypeSpec.Versioning.added(version: EnumMember)
```

##### Target

`Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface`

##### Parameters

| Name    | Type         | Description                               |
| ------- | ------------ | ----------------------------------------- |
| version | `EnumMember` | The version that the target was added in. |

##### Examples

```tsp
@added(Versions.v2)
op addedInV2(): void;

@added(Versions.v2)
model AlsoAddedInV2 {}

model Foo {
  name: string;

  @added(Versions.v3)
  addedInV3: string;
}
```

#### `@madeOptional`

Identifies when a target was made optional.

```typespec
@TypeSpec.Versioning.madeOptional(version: EnumMember)
```

##### Target

`ModelProperty`

##### Parameters

| Name    | Type         | Description                                       |
| ------- | ------------ | ------------------------------------------------- |
| version | `EnumMember` | The version that the target was made optional in. |

##### Examples

```tsp
model Foo {
  name: string;

  @madeOptional(Versions.v2)
  nickname?: string;
}
```

#### `@madeRequired`

Identifies when a target was made required.

```typespec
@TypeSpec.Versioning.madeRequired(version: EnumMember)
```

##### Target

`ModelProperty`

##### Parameters

| Name    | Type         | Description                                       |
| ------- | ------------ | ------------------------------------------------- |
| version | `EnumMember` | The version that the target was made required in. |

##### Examples

```tsp
model Foo {
  name: string;

  @madeRequired(Versions.v2)
  nickname: string;
}
```

#### `@removed`

Identifies when the target was removed.

```typespec
@TypeSpec.Versioning.removed(version: EnumMember)
```

##### Target

`Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface`

##### Parameters

| Name    | Type         | Description                                 |
| ------- | ------------ | ------------------------------------------- |
| version | `EnumMember` | The version that the target was removed in. |

##### Examples

```tsp
@removed(Versions.v2)
op removedInV2(): void;

@removed(Versions.v2)
model AlsoRemovedInV2 {}

model Foo {
  name: string;

  @removed(Versions.v3)
  removedInV3: string;
}
```

#### `@renamedFrom`

Identifies when the target has been renamed.

```typespec
@TypeSpec.Versioning.renamedFrom(version: EnumMember, oldName: valueof string)
```

##### Target

`Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface`

##### Parameters

| Name    | Type             | Description                                 |
| ------- | ---------------- | ------------------------------------------- |
| version | `EnumMember`     | The version that the target was renamed in. |
| oldName | `valueof string` | The previous name of the target.            |

##### Examples

```tsp
@renamedFrom(Versions.v2, "oldName")
op newName(): void;
```

#### `@returnTypeChangedFrom`

Declares that the return type of an operation has changed starting at a given version,
while keeping earlier versions consistent with the previous return type.

This decorator is used to track return type changes across API versions. When applied,
the operation will return `oldType` in versions before the specified `version`,
and the current return type definition in the specified version and later.

```typespec
@TypeSpec.Versioning.returnTypeChangedFrom(version: EnumMember, oldType: unknown)
```

##### Target

`Operation`

##### Parameters

| Name    | Type         | Description                                                                                                                                                              |
| ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| version | `EnumMember` | The version when the return type change takes effect. The new return type applies<br />from this version onwards, while the old return type applies to earlier versions. |
| oldType | `unknown`    | The previous return type used before the specified version.                                                                                                              |

##### Examples

```tsp
// In v1: returns a string
// In v2+: returns an int32
@returnTypeChangedFrom(Versions.v2, string)
op getUserId(): int32;
```

#### `@typeChangedFrom`

Declares that the type of a model property has changed starting at a given version,
while keeping earlier versions consistent with the previous type.

This decorator is used to track type changes across API versions. When applied,
the property will use `oldType` in versions before the specified `version`,
and the current type definition in the specified version and later.

```typespec
@TypeSpec.Versioning.typeChangedFrom(version: EnumMember, oldType: unknown)
```

##### Target

`ModelProperty`

##### Parameters

| Name    | Type         | Description                                                                                                                                         |
| ------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| version | `EnumMember` | The version when the type change takes effect. The new type applies<br />from this version onwards, while the old type applies to earlier versions. |
| oldType | `unknown`    | The previous type used before the specified version.                                                                                                |

##### Examples

```tsp
model Foo {
  // In v1: id is a string
  // In v2+: id is an int32
  @typeChangedFrom(Versions.v2, string)
  id: int32;
}
```

#### `@useDependency`

Identifies that a namespace or a given versioning enum member relies upon a versioned package.

```typespec
@TypeSpec.Versioning.useDependency(...versionRecords: EnumMember[])
```

##### Target

`EnumMember | Namespace`

##### Parameters

| Name           | Type           | Description                                                           |
| -------------- | -------------- | --------------------------------------------------------------------- |
| versionRecords | `EnumMember[]` | The dependent library version(s) for the target namespace or version. |

##### Examples

###### Select a single version of `MyLib` to use

```tsp
@useDependency(MyLib.Versions.v1_1)
namespace NonVersionedService;
```

###### Select which version of the library match to which version of the service.

```tsp
@versioned(Versions)
namespace MyService1;
enum Version {
  @useDependency(MyLib.Versions.v1_1) // V1 use lib v1_1
  v1,
  @useDependency(MyLib.Versions.v1_1) // V2 use lib v1_1
  v2,
  @useDependency(MyLib.Versions.v2) // V3 use lib v2
  v3,
}
```

#### `@versioned`

Identifies that the decorated namespace is versioned by the provided enum.

```typespec
@TypeSpec.Versioning.versioned(versions: Enum)
```

##### Target

`Namespace`

##### Parameters

| Name     | Type   | Description                                     |
| -------- | ------ | ----------------------------------------------- |
| versions | `Enum` | The enum that describes the supported versions. |

##### Examples

```tsp
@versioned(Versions)
namespace MyService;
enum Versions {
  v1,
  v2,
  v3,
}
```

---

### Overview (`packages/xml/README.md`)

# @typespec/xml

TypeSpec library providing xml bindings

## Install

```bash
npm install @typespec/xml
```

## Decorators

### TypeSpec.Xml

- [`@attribute`](#@attribute)
- [`@name`](#@name)
- [`@ns`](#@ns)
- [`@nsDeclarations`](#@nsdeclarations)
- [`@unwrapped`](#@unwrapped)

#### `@attribute`

Specify that the target property should be encoded as an XML attribute instead of node.

```typespec
@TypeSpec.Xml.attribute
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

###### Default

```tsp
model Blob {
  id: string;
}
```

```xml
<Blob>
  <id>abcdef</id>
</Blob>
```

###### With `@attribute`

```tsp
model Blob {
  @attribute id: string;
}
```

```xml
<Blob id="abcdef">
</Blob>
```

#### `@name`

Provide the name of the XML element or attribute. This means the same thing as
`@encodedName("application/xml", value)`

```typespec
@TypeSpec.Xml.name(name: valueof string)
```

##### Target

`unknown`

##### Parameters

| Name | Type             | Description                              |
| ---- | ---------------- | ---------------------------------------- |
| name | `valueof string` | The name of the XML element or attribute |

##### Examples

```tsp
@name("XmlBook")
model Book {
  @name("XmlId") id: string;
  @encodedName("application/xml", "XmlName") name: string;
  content: string;
}
```

```xml
<XmlBook>
  <XmlId>string</XmlId>
  <XmlName>string</XmlName>
  <content>string</content>
</XmlBook>
```

#### `@ns`

Specify the XML namespace for this element. It can be used in 2 different ways:

1. `@ns("http://www.example.com/namespace", "ns1")` - specify both namespace and prefix
2. `@Xml.ns(Namespaces.ns1)` - pass a member of an enum decorated with `@nsDeclaration`

```typespec
@TypeSpec.Xml.ns(ns: string | EnumMember, prefix?: valueof string)
```

##### Target

`unknown`

##### Parameters

| Name   | Type                   | Description                                                                       |
| ------ | ---------------------- | --------------------------------------------------------------------------------- |
| ns     | `string \| EnumMember` | The namespace URI or a member of an enum decorated with `@nsDeclaration`.         |
| prefix | `valueof string`       | The namespace prefix. Required if the namespace parameter was passed as a string. |

##### Examples

###### With strings

```tsp
@ns("https://example.com/ns1", "ns1")
model Foo {
  @ns("https://example.com/ns1", "ns1")
  bar: string;

  @ns("https://example.com/ns2", "ns2")
  bar: string;
}
```

###### With enum

```tsp
@Xml.nsDeclarations
enum Namespaces {
  ns1: "https://example.com/ns1",
  ns2: "https://example.com/ns2",
}

@Xml.ns(Namespaces.ns1)
model Foo {
  @Xml.ns(Namespaces.ns1)
  bar: string;

  @Xml.ns(Namespaces.ns2)
  bar: string;
}
```

#### `@nsDeclarations`

Mark an enum as declaring XML namespaces. See `@ns`

```typespec
@TypeSpec.Xml.nsDeclarations
```

##### Target

`Enum`

##### Parameters

None

#### `@unwrapped`

Specify that the target property shouldn't create a wrapper node. This can be used to flatten list nodes into the model node or to include raw text in the model node.
It cannot be used with `@attribute`.

```typespec
@TypeSpec.Xml.unwrapped
```

##### Target

`ModelProperty`

##### Parameters

None

##### Examples

###### Array property default

```tsp
model Pet {
  tags: Tag[];
}
```

```xml
<XmlPet>
  <ItemsTags>
    <XmlTag>
      <name>string</name>
    </XmlTag>
  </ItemsTags>
</XmlPet>
```

###### Array property with `@unwrapped`

```tsp
model Pet {
  @unwrapped tags: Tag[];
}
```

```xml
<XmlPet>
  <XmlTag>
    <name>string</name>
  </XmlTag>
</XmlPet>
```

###### String property default

```tsp
model BlobName {
  content: string;
}
```

```xml
<BlobName>
  <content>
    abcdef
  </content>
</BlobName>
```

###### Array property with `@unwrapped`

```tsp
model BlobName {
  @unwrapped content: string;
}
```

```xml
<BlobName>
  abcdef
</BlobName>
```

---

### Overview (`packages/http-client-csharp/generator/README.md`)

# Microsoft TypeSpec Generator

The **Microsoft TypeSpec Generator** is a code generation library that is bundled with the `@typespec/http-client-csharp` emitter to transform TypeSpec API definitions into strongly-typed C# client libraries for accessing RESTful web services. The generator provides a modular, extensible architecture that supports multiple output formats and customization scenarios.

## Table of Contents

- [Architecture Overview](#architecture-overview)
- [Prerequisites](#prerequisites)
- [Build](#build)
- [Test](#test)

## Architecture Overview

See the architecture documentation [here](docs/architecture.md).

## Prerequisites

- [.NET Core SDK (8.0.x)](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)

## Build

1. `dotnet build` (at root)

## Test

1. `dotnet test` (at root)

---

### Overview (`packages/http-client-java/emitter/README.md`)

# Java emitter code model

The TypeScript emitter converts the TCGC SDK model into the data contract consumed
by the Java generator. The interfaces, factories, and mutation helpers in
`src/common/` are owned by this emitter; they do not require the AutoRest codemodel
or codegen npm packages.

Model nodes are plain objects. Schema types use their existing `type` field for
narrowing, and response/parameter helpers use existing wire fields rather than
adding private discriminators. `common/schemas.ts` registers schemas in the
collections expected by Java and preserves the existing deduplication rules.

Keep object identity intact when modifying this code: recursive schemas, parent
clients, parameters, and properties can share references or form cycles. Factories
must also preserve metadata defaults, omitted fields, and container-copy behavior.
Do not replace these references with JSON clones.

The interchange format remains `code-model.yaml`, serialized as YAML 1.1 for the
Java backend's SnakeYAML reader. This is still the AutoRest-derived code-model
contract; removing the npm dependencies does not change the Java backend or the
external AutoRest flow.

`test/code-model.test.ts` covers model initialization, registration, reference
identity, signature filtering, plain-object graphs, and TypeSpec-to-YAML snapshots
captured before the dependency removal, including LRO, subclient, multipart, and
XML-bytes scenarios. Snapshot keys are sorted without cloning away aliases, so
mapping order does not obscure contract changes.

---

### Overview (`packages/http-client-java/generator/README.md`)

# Microsoft Java client generator

The **Microsoft Java client generator** tool generates client libraries for accessing RESTful web services.

## Table of Contents

- [Prerequisites](#prerequisites)
- [Build](#build)
- [Test](#test)

## Prerequisites

- [Java 17 or above](https://docs.microsoft.com/java/openjdk/download)
- [Maven](https://maven.apache.org/download.cgi)

## Build

1. `mvn clean compile` (from packages/http-client-java/generator directory)

## Test

1. `mvn clean test` (from packages/http-client-java/generator directory)

## Debug

### Debugging Java Code

Run `Main` class

- Add `--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED` to VM options.

---

### Overview (`packages/samples/specs/grpc-kiosk-example/README.md`)

# Introduction

This example demonstrates the use of Protocol Buffers to define and implement a networked API. The Kiosk API allows users to manage a collection of displays that are able to display digital signs containing text and images. The Kiosk API includes a streaming method that allows displays to immediately update in response to configuration changes on the API server. The Kiosk API is implemented using gRPC, which includes support for streaming APIs. All non-streaming API methods can also be provided as REST services using standard gRPC to JSON transcoding.

The original gRPC-based API definition is in the [googleapis/kiosk](https://github.com/googleapis/kiosk/) repository.

We have taken the `gRPC` representation of this service and converted it into `TypeSpec` to understand what gaps might be in the language. Note we're not trying to create an `TypeSpec` which could create the equivalent `protobuf` as an output format, but are focusing on the swagger created from both `gRPC` and `TypeSpec` and trying to understand the differences.

## Files

- [kiosk.proto](kiosk.proto) - The original [kiosk.proto](https://github.com/googleapis/kiosk/blob/master/protos/kiosk.proto).
- [kiosk.swagger.json](kiosk.swagger.json) - Swagger generated from the `kiosk.proto` file using `protoc-gen-openapiv2`.
- [kiosk.tsp](kiosk.tsp) - A hand-written TypeSpec file which tries to stay as close as possible to a RPC based request/response model.
- [types.tsp](types.tsp) - Some generic types which could move into a standard type library.
- [openapi.json](openapi.json) - Swagger generated by `tsp compile` from `kiosk.tsp`.

## Open questions and comments

### `rpc CreateKiosk(Kiosk)` is broken in OpenAPI

The gRPC definition of `CreateKiosk`:

```protobuf
// Create a kiosk. This enrolls the kiosk for sign display.
rpc CreateKiosk(Kiosk) returns (Kiosk) {
    option (google.api.http) = { post: "/v1/kiosks" };
}
```

doesn't translate at all to OpenAPI and the Swagger produced has no request body:

```json
"post": {
   "summary": "Create a kiosk. This enrolls the kiosk for sign display.",
   "operationId": "Display_CreateKiosk",
   "responses": {
       "200": {
       "description": "A successful response.",
       "schema": {
           "$ref": "#/definitions/kioskKiosk"
       }
       },
       "default": {
       "description": "An unexpected error response.",
       "schema": {
           "$ref": "#/definitions/rpcStatus"
       }
       }
   },
   "tags": [
       "Display"
   ]
   }
}
```

TypeSpec has an advantage as it won't even allow the corresponding `op` to compile and it will throw an error that there isn't a unique body specified. Alteratively, the `library` service does it better and in a way that translates cleanly to TypeSpec:

```protobuf
// Request message for LibraryService.CreateBook.
message CreateBookRequest {
    // The name of the shelf in which the book is created.
    string name = 1 [
        (google.api.field_behavior) = REQUIRED,
        (google.api.resource_reference).type = "Shelf"
    ];

    // The book to create.
    Book book = 2 [(google.api.field_behavior) = REQUIRED];
}

// Creates a book, and returns the new Book.
rpc CreateBook(CreateBookRequest) returns (Book) {
    option (google.api.http) = {
      post: "/v1/{name=shelves/*}/books"
      body: "book"
    };
    option (google.api.method_signature) = "name,book";
}
```

### Using `...` in Request parameters

In this example and the Library example we see a few different patterns on how a gRPC `rpc` definition uses different `message`. While some directly use things that look like TypeSpec models as request and response messages, a more general patter is that a gRPC op `Foo` usually has `FooRequest` and `FooResponse` messages which embed models inside, e.g.

a natural direct mapping of:

```protobuf
message GetKioskRequest {
  // Required.
  int32 id = 1;
}

// Get a kiosk.
rpc GetKiosk(GetKioskRequest) returns (Kiosk) {
    option (google.api.http) = { get: "/v1/kiosks/{id}" };
}
```

would be

```
model GetKioskRequest {
    @path
    id: int32;
}

@doc("Get a kiosk.")
@get
@route("kiosks/{id}")
op GetKiosk(... GetKioskRequest): Kiosk | RpcStatus;
```

This produces slightly different, but functionality equivalent swagger in that the gRPC generator inline the parameter id, while TypeSpec create a `"$ref": "#/parameters/GetKioskRequest"` which points to a single parameter, `id`.

If we wrote the TypeSpec directly with the id specified in the `op` parameters we get equivalent to the gRPC version:

```
@doc("Get a kiosk.")
@get
@route("kiosks/{id}")
op GetKiosk(@path id: int32): Kiosk | RpcStatus;
```

the downside with this approach is that it's not as convenient to add documentation inside the parameter. Could we perhaps add a new decorator @parameter_doc("id","This is a unique identified") that we add to the `op` ?

---

### Overview (`packages/samples/specs/grpc-library-example/README.md`)

# Introduction

This is a Google example service representing a simple digital library.
It manages a collection of shelf resources, and each shelf owns a collection
of book resources.

The original gRPC-based API definition is in the [googleapis/googleapis](https://github.com/googleapis/googleapis/) repository.

It follows the [Google API Design Guidelines](https://cloud.google.com/apis/design). We have taken the `gRPC` representation of this service and converted it into `TypeSpec` to understand what gaps might be in the language. Note we're not trying to create an `TypeSpec` which could create the equivalent `protobuf` as an output format, but are focusing on the swagger created from both `gRPC` and `TypeSpec` and trying to understand the differences.

## Files

- [library.proto](library.proto) - The original `proto` file from the [googleapis/googleapis](https://github.com/googleapis/googleapis/tree/master/google/example/library) repo.
- [library.swagger.json](library.swagger.json) - Swagger generated from the `library.proto` file using `protoc-gen-openapiv2`.
- [library.tsp](library.tsp) - A hand-written TypeSpec file which tries to stay as close as possible to a RPC based request/response model.
- [openapi.json](openapi.json) - Swagger generated by `tsp compile` from `library.tsp`.

## Open Questions

### How to handle a empty response

for an op of form `op Foo(): null` we currently emit the `responses` block as follows:

```json
 "responses": {
    "200": {
        "description": "Null response"
    },
```

whereas when generated from gRPC definition it is:

```json
"responses": {
    "200": {
        "description": "A successful response.",
        "schema": {
            "properties": {}
        }
    },
```

### GRPC path mapping

Google uses structured names for [resource names](https://cloud.google.com/apis/design/resource_names). e.g.

```protobuf
// A Shelf contains a collection of books with a theme.
message Shelf {
  option (google.api.resource) = {
    type: "library-example.googleapis.com/Shelf",
    pattern: "shelves/{shelf_id}"
  };
  // The resource name of the shelf.
  // Shelf names have the form `shelves/{shelf_id}`.
  // The name is ignored when creating a shelf.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "library-example.googleapis.com/Shelf"
  ];
}
```

Since the name includes part of the standard REST path, gRPC allows a more complex path mapping for the gRPC reverse proxy - (ref: [gRPC transcoding](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule)). In particular it allows for constructs like:

```
// Gets a shelf. Returns NOT_FOUND if the shelf does not exist.
  rpc GetShelf(GetShelfRequest) returns (Shelf) {
    option (google.api.http) = {
      get: "/v1/{name=shelves/*}"
    };
    option (google.api.method_signature) = "name";
  }
```

This means the URI for a GET on a shelf with name `shelves/fiction` is `/v1/shelves/fiction`. The grpc-openapiv2 generator doesn't handle this path mapping so you actually get invalid paths in the swagger. See the [Kiosk gRPC example](../grpc-kiosk-example) for a gRPC examples with OpenAPI compatible path definitions.

---

### Overview (`packages/samples/specs/local-typespec/README.md`)

# Installing TypeSpec to project local path

This sample shows how to install TypeSpec locally to a project and have the VS Code
extension use its locally installed language server.

See `typespec.tsp-server.path` in [.vscode/settings.json](.vscode/settings.json) and
`@typespec/compiler` dev dependency in [package.json](package.json).

## Steps

### 1. Install TypeSpec to project:

```
npm install --save-dev @typespec/compiler
```

### 2. Configure path in VS Code

- File -> Preferences
- Search for TypeSpec
- Click on Workspace tab
- Set `typespec.tsp-server.path` to `${workspaceFolder}/node_modules/@typespec/compiler`

  (NOTE: If the TypeSpec project is not at the root of the workspace, adjust the path accordingly.
  For example, `${workspaceFolder}/path/from/workspace/to/project/node_modules/@typespec/compiler`)

### 3. Commit settings.json and package.json changes

---

### Overview (`docs/samples/client/csharp/SampleService/readme.md`)

# Sample Service

This package represents a sample HTTP service and the generated code produced after compiling with the `@typespec/http-client-csharp` emitter. The package makes use of a logging plugin in order to enrich each method with logs indicating when the method is called and any exceptions thrown from the method. The `logging-plugin` is specified in the `package.json` file. In order to compile this project locally, clone the repo, navigate to the `SampleService` directory and run the following command:
`tsp compile .`

---

### Overview (`docs/samples/client/csharp/oauth/readme.md`)

# OAuth 2.0 Credential Support

This guide provides example implementations of OAuth 2.0 credentials to enable secure authentication in clients generated by TypeSpec.
With this approach, you can define OAuth 2.0 authentication directly in your TypeSpec files and supply custom credential implementations for a smooth, end-to-end authentication flow.

For more details, refer to the TypeSpec documentation: [Oauth2Auth](https://typespec.io/docs/libraries/http/reference/js-api/interfaces/oauth2auth/)

## Getting Started

- [Creating a client with OAuth Token](#create-custom-client-constructor-to-support-oauth-token)
- [Example implementation of AuthenticationTokenProvider](#example-implementation-of-authenticationtokenprovider)
- [Example usage of AuthenticationTokenProvider and Custom Client](#example-usage-of-authenticationtokenprovider-and-custom-client)

### Create custom client constructor to support OAuth token

This constructor initializes a new instance of the `SampleTypeSpecClient` class and sets a client pipeline with OAuth2 bearer token authentication using the provided `AuthenticationTokenProvider` and endpoint URI.

```csharp
using System.ClientModel;
using System.ClientModel.Primitives;

/// <summary>
/// Customize client to add custom constructor.
/// </summary>
public partial class SampleTypeSpecClient
{
  public SampleTypeSpecClient(Uri uri, AuthenticationTokenProvider tokenProvider)
  {
      _endpoint = uri;
      var options = new ClientPipelineOptions();
      Pipeline = ClientPipeline.Create(
          options,
          perCallPolicies: ReadOnlySpan<PipelinePolicy>.Empty,
          perTryPolicies: [new OAuth2BearerTokenAuthenticationPolicy(tokenProvider, flows)],
          beforeTransportPolicies: ReadOnlySpan<PipelinePolicy>.Empty
      );
  }
}
```

The full code is available [here](https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Custom/SampleTypeSpecClient.cs).

### Example implementation of AuthenticationTokenProvider

Below is an example implementation of the `AuthenticationTokenProvider` class that supports the client credentials flow.

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Example usage of AuthenticationTokenProvider and Custom Client

This example demonstrates how to use the `AuthenticationTokenProvider` with the custom client constructor to authenticate and make a request to the API.

```csharp
AuthenticationTokenProvider provider = new ClientCredentialTokenProvider("myClientId", "myClientSecret");
var client = new SampleTypeSpecClient(new Uri("http://localhost:5000"), provider);
client.Widget("myId");
```

---

### Overview (`docs/samples/client/java/oauth/README.md`)

# OAuth 2.0 Credential Support

This guide provides example implementations of OAuth 2.0 credentials to enable secure authentication in clients generated by TypeSpec.
With this approach, you can define OAuth 2.0 authentication directly in your TypeSpec files and supply custom credential implementations for a smooth, end-to-end authentication flow.

For more details, refer to the TypeSpec documentation: [Oauth2Auth](https://typespec.io/docs/libraries/http/reference/js-api/interfaces/oauth2auth/)

- [OAuth 2.0 Credential Support](#oauth-20-credential-support)
  - [Generate a client with OAuth2Auth](#generate-a-client-with-oauth2auth)
  - [Example implementation of OAuthTokenCredential](#example-implementation-of-oauthtokencredential)
  - [Example usage of OAuthTokenCredential and Custom Client](#example-usage-of-oauthtokencredential-and-custom-client)

### Generate a client with OAuth2Auth

In your TypeSpec, create a client using the `OAuth2Auth` flow:

```typespec
import "@typespec/http";

using TypeSpec.Http;

@useAuth(
  OAuth2Auth<[
    {
      type: OAuth2FlowType.clientCredentials,
      tokenUrl: "https://tokenUrl",
      scopes: ["scope"],
    }
  ]>
)
@service(#{ title: "Example Server API" })
@server("https://endpoint", "Example Server Endpoint")
namespace ExampleServer {
  model Result {
    value: string;
  }

  // Test API endpoint
  @route("/api/getValue")
  @get
  op getResult(): Result[];
}
```

### Example implementation of OAuthTokenCredential

Below is an example implementation of the `OAuthTokenCredential` class that supports the client credentials flow. This sample should be modified to meet your needs, including:

- Choosing the appropriate OAuth flow.
- Choosing the appropriate JSON library for your project. Jackson is used here only as an example.
- Appropriate error handling and logging.

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Example usage of OAuthTokenCredential and Custom Client

This example demonstrates how to use the `AuthenticationTokenProvider` with the custom client constructor to authenticate and make a request to the API.

```java
TestCredential credential = new TestCredential().setClientId("myClientId").setClientSecret("myClientSecret");
var client = new ExampleServerClientBuilder().credential(credential).build();
client.getResult();
```

---

### Overview (`docs/samples/client/js/oauth/readme.md`)

# Authenticating with OAuth2TokenCredential

This readme demonstrates how to implement `OAuth2TokenCredential` using popular third-party authentication libraries and integrate it with the generated TypeSpec client. It provides examples for both Authorization Code Flow using `@auth0/auth0-spa-js` and Client Credentials Flow using `auth0`.

## Table of contents

- [Creating OAuth2 Credential](#creating-oauth2-credential-with-third-party-library)
  - [Example with `@auth0/auth0-spa-js`](#authorization-code-flow-with-auth0auth0-spa-js)
  - [Example with `auth0`](#client-credential-flow-with-auth0)

## Create OAuth2 Credential

#### Authorization Code Flow with `@auth0/auth0-spa-js`

The following sample illustrates using `@auth0/auth0-spa-js` to acquire the access token for authorization code flow. The credential created is passed into the constructor of the `SampleTypeSpecClient` and the client will set the appropriate authentication policy using the information provided. The method `getOAuth2Token` will be called to get the token to authenticate the request.

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### Client Credential Flow with `auth0`

The following sample illustrates using `auth0` to acquire the access token for authorization code flow. The credential created is passed into the constructor of the `SampleTypeSpecClient` and the client will set the appropriate authentication policy using the information provided. The method `getOAuth2Token` will be called to get the token to authenticate the request.

```ts
import { OAuth2TokenCredential, ClientCredentialsFlow } from "@typespec/ts-http-runtime";
import { AuthenticationClient } from "auth0";
import { SampleTypeSpecClient } from "SampleTypeSpecSDK";

// Create an OAuth2 credential that implements authorization code flow
const credential: OAuth2TokenCredential<ClientCredentialsFlow> = {
  async getOAuth2Token(flows: ClientCredentialsFlow[]) {
    const { tokenUrl } = flows[0];
    const option = {
      domain: tokenUrl,
      clientId: "SampleClientID",
      clientSecret: "SampleClientSecret",
    };
    const client = new AuthenticationClient(option);
    const response = await client.oauth.clientCredentialsGrant({ audience: "SampleAudience" });
    return response.data.access_token;
  },
};

// Authentication shemes that the services allow
const authorizationCodeScheme: AuthScheme = {
  kind: "oauth2",
  flows: [
    {
      kind: "clientCredentials",
      tokenUrl: "https://example.com/token",
      scopes: ["sampleScope1", "sampleScope2"],
    },
  ],
};

// Pass the credential to the client and use the client to make a request to the service
const client = new SampleTypeSpecClient(credential, {
  authSchemes: [authorizationCodeScheme],
});
```

---

### Overview (`docs/samples/client/python/oauth/README.md`)

# OAuth 2.0 Credential Support

This guide provides example implementations of OAuth 2.0 credentials to enable secure authentication in clients generated by TypeSpec. With this approach, you can define OAuth 2.0 authentication directly in your TypeSpec files and supply custom credential implementations for a smooth, end-to-end authentication flow.

For more details, refer to the TypeSpec documentation: [Oauth2Auth](https://typespec.io/docs/libraries/http/reference/js-api/interfaces/oauth2auth/)

# Getting Started

## Define OAuth 2.0 in TypeSpec

In the .tsp file, declare the use of OAuth 2.0:

```python
@useAuth(OAuth2Auth<[
    {
      type: OAuth2FlowType.clientCredentials,
      authorizationUrl: "https://auth.example.com/authorize",
      tokenUrl: "https://auth.example.com/token",
      scopes: ["read", "write"],
    }
  ]>
)
```

## Implement the OAuth2 Credential

Follow the sample implementation to create a credential class that includes the `get_token_info` method, which returns an `AccessTokenInfo` object. This follows the credential interface defined in the [corehttp](https://learn.microsoft.com/python/api/overview/azure/corehttp-readme?view=azure-python-preview&preserve-view=true) package.

## Use the Credential with the Generated Client

```py
credential = MyOAuth2Credential()
client = MyGeneratedClient(endpoint, credential)

result = client.my_operation()
print(result)
```

---

### Overview (`packages/http-server-csharp/test/snapshots/sample-service/README.md`)

---
title: Next Steps
---

# Next Steps

- Use the SwaggerUI endpoint to test out the running service
- Update business logic mocks with real business logic
  - `mocks/Pets.cs`
  - `mocks/Dogs.cs`
- Update `mocks/MockRegistration.cs` if you update the constructor of business logic implementations.
- Update development and production configuration to suit your needs

## More Information

- See [Code Layout](docs/usage.md) for information about the generated code
- See [Emitter Usage](docs/emitter.md) for details on how to use the emitter.
- File issues or provide feedback in [TypeSpec Issues](https://github.com/microsoft/typespec/issues/new/choose)
- Get information about Typespec on the [TypeSpec website](https://typespec.io)

---

### Packages Http Client Csharp Docs Index (`packages/http-client-csharp/docs/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for emitting Http Client libraries for C#.

## Install

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

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

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

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

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

## Generator plugins

[See documentation](./plugins.md)

## TypeSpec.HttpClient

## TypeSpec.HttpClient.CSharp

### Decorators

- [`@dynamicModel`](./decorators.md#@TypeSpec.HttpClient.CSharp.dynamicModel)

---

### Packages Http Server Csharp Docs Index (`packages/http-server-csharp/docs/index.mdx`)

---
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)
[Overview of Generated Code](./usage.md)

---

### Website Src Content Docs Docs Getting Started Getting Started (`website/src/content/docs/docs/getting-started/getting-started.md`)

---
id: getting-started
title: Getting Started
---

- [Get started with TypeSpec for REST](./getting-started-rest/01-setup-basic-syntax.mdx)

---

### Website Src Content Docs Docs Language Basics Overview (`website/src/content/docs/docs/language-basics/overview.md`)

---
id: overview
title: Overview
description: "Language basics - overview"
llmstxt: true
---

This document provides a concise overview of the language concepts in TypeSpec. It serves as a quick reference guide rather than an in-depth tutorial.

## Declarations

- Names of declarations must be unique across different types within the same scope. For instance, the following is not permissible:
  
  ```typespec
  model Dog {}
  namespace Dog {}
  ```

## Imports

_For more details, see: [Imports](./imports.md)_

| Feature              | Example                   |
| -------------------- | ------------------------- |
| Import TypeSpec file | `import "./models.tsp"`   |
| Import JS file       | `import "./models.js"`    |
| Import Library       | `import "@typespec/rest"` |

## Namespaces

_For more details, see: [Namespaces](./namespaces.md)_

| Feature           | Example                      |
| ----------------- | ---------------------------- |
| Declare namespace | `namespace PetStore {}`      |
| File namespace    | `namespace PetStore;`        |
| Nested namespace  | `namespace PetStore.Models;` |
| Using namespace   | `using PetStore.Models;`     |

## Decorators

_For more details, see: [Decorators](./decorators.md)_

| Feature                      | Example                                                                             |
| ---------------------------- | ----------------------------------------------------------------------------------- |
| Use decorator                | `@mark`                                                                             |
| Use decorator with arguments | `@tag("abc")`                                                                       |
| Declare a decorator in JS    | `export function $tag(context: DecoratorContext, target: Type, name: string) {...}` |
| Save state in decorator      | `context.program.stateMap(key).set(target, <value>)`                                |
| Augment decorator            | `@@tag(MyType, "abc");`                                                             |

## Scalars

_For more details, see: [Scalars](./scalars.md)_

| Feature            | Example                                     |
| ------------------ | ------------------------------------------- |
| Scalar declaration | `scalar ternary`                            |
| Extend scalar      | `scalar Password extends string`            |
| Template scalar    | `@doc(T) scalar Password<T extends string>` |

## Models

_For more details, see: [Models](./models.md)_

| Feature                        | Example                               |
| ------------------------------ | ------------------------------------- |
| Model declaration              | `model Pet {}`                        |
| Model inheritance              | `model Dog extends Pet {}`            |
| scalar is                      | `model uuid extends string;`          |
| Model spread                   | `model Dog {...Animal}`               |
| Property                       | `model Dog { name: string }`          |
| Optional property              | `model Dog { owner?: string }`        |
| Optional property with default | `model Dog { name?: string = "Rex" }` |
| Model template                 | `model Pet<T> { t: T }`               |

## Operations

_For more details, see: [Operations](./operations.md)_

| Feature                       | Example                                          |
| ----------------------------- | ------------------------------------------------ |
| Operation declaration         | `op ping(): void`                                |
| Operation with parameters     | `op upload(filename: string, data: bytes): void` |
| Operation with return type    | `op health(): HealthStatus`                      |
| Operation with multiple types | `op health(): HealthStatus \| ErrorResponse`     |
| Operation template            | `op getter<T>(id: string): T`                    |
| Operation is                  | `op getPet is getter<Pet>;`                      |

## Interfaces

_For more details, see: [Interfaces](./interfaces.md)_

| Feature               | Example                                |
| --------------------- | -------------------------------------- |
| Interface declaration | `interface PetStore { list(): Pet[] }` |
| Interface composition | `interface PetStore extends Store { }` |
| Interface template    | `interface Restful<T> { list(): T[] }` |

## Templates

_For more details, see: [Templates](./templates.md)_

| Feature                           | Example                                             |
| --------------------------------- | --------------------------------------------------- |
| Simple template                   | `model Response<T> {value: T}`                      |
| Template with multiple parameters | `model Response<K, V> {key: K, value: T}`           |
| Template default                  | `model Response<T = string> {value: T}`             |
| Template constraints              | `model Response<T extends {id: string}> {value: T}` |
| Template constraints and defaults | `model Response<T extends string = ""> {value: T}`  |

## Enums

_For more details, see: [Enums](./enums.md)_

| Feature            | Example                                        |
| ------------------ | ---------------------------------------------- |
| Enum declaration   | `enum Direction {Up, Down}`                    |
| Enum string values | `enum Direction {Up: "up", Down: "down"}`      |
| Enum int values    | `enum Size {Small: 1000, Large: 2000}`         |
| Enum float values  | `enum Part {Quarter: 0.25, Half: 0.5}`         |
| Enum composing     | `enum Direction2D {...Direction, Left, Right}` |

## Unions

_For more details, see: [Unions](./unions.md)_

| Feature                 | Example                          |
| ----------------------- | -------------------------------- |
| Union declaration       | `"cat" \| "dog"`                 |
| Named union declaration | `union Pet {cat: Cat, dog: Dog}` |

## Intersections

_For more details, see: [Intersections](./intersections.md)_

| Feature                  | Example        |
| ------------------------ | -------------- |
| Intersection declaration | `Pet & Animal` |

## Type literals

_For more details, see: [Type literals](./type-literals.md)_

| Feature           | Example                                                  |
| ----------------- | -------------------------------------------------------- |
| String            | `"Hello world!"`                                         |
| Multi line String | `"""\nHello world!\n"""` (\n) represent actual new lines |
| Int               | `10`                                                     |
| Float             | `10.0`                                                   |
| Boolean           | `false`                                                  |

## Aliases

_For more details, see: [Aliases](./alias.md)_

| Feature           | Example                           |
| ----------------- | --------------------------------- |
| Alias declaration | `alias Options = "one" \| "two";` |

---

### Website Src Content Docs Docs Emitters Graphql Reference Index (`website/src/content/docs/docs/emitters/graphql/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for emitting GraphQL

## Install

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

```bash
npm install @typespec/graphql
```

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

```bash
npm install --save-peer @typespec/graphql
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

## TypeSpec.GraphQL

### Decorators

- [`@compose`](./decorators.md#@TypeSpec.GraphQL.compose)
- [`@graphqlInterface`](./decorators.md#@TypeSpec.GraphQL.graphqlInterface)
- [`@mutation`](./decorators.md#@TypeSpec.GraphQL.mutation)
- [`@operationFields`](./decorators.md#@TypeSpec.GraphQL.operationFields)
- [`@query`](./decorators.md#@TypeSpec.GraphQL.query)
- [`@schema`](./decorators.md#@TypeSpec.GraphQL.schema)
- [`@specifiedBy`](./decorators.md#@TypeSpec.GraphQL.specifiedBy)
- [`@subscription`](./decorators.md#@TypeSpec.GraphQL.subscription)

## TypeSpec.GraphQL.Schema

### Models

- [`SchemaOptions`](./data-types.md#TypeSpec.GraphQL.Schema.SchemaOptions)

---

### Website Src Content Docs Docs Emitters Json Schema Reference Index (`website/src/content/docs/docs/emitters/json-schema/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for emitting TypeSpec to JSON Schema and converting JSON Schema to TypeSpec

## Install

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

```bash
npm install @typespec/json-schema
```

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

```bash
npm install --save-peer @typespec/json-schema
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

## TypeSpec.JsonSchema

### Decorators

- [`@baseUri`](./decorators.md#@TypeSpec.JsonSchema.baseUri)
- [`@contains`](./decorators.md#@TypeSpec.JsonSchema.contains)
- [`@contentEncoding`](./decorators.md#@TypeSpec.JsonSchema.contentEncoding)
- [`@contentMediaType`](./decorators.md#@TypeSpec.JsonSchema.contentMediaType)
- [`@contentSchema`](./decorators.md#@TypeSpec.JsonSchema.contentSchema)
- [`@extension`](./decorators.md#@TypeSpec.JsonSchema.extension)
- [`@id`](./decorators.md#@TypeSpec.JsonSchema.id)
- [`@jsonSchema`](./decorators.md#@TypeSpec.JsonSchema.jsonSchema)
- [`@maxContains`](./decorators.md#@TypeSpec.JsonSchema.maxContains)
- [`@maxProperties`](./decorators.md#@TypeSpec.JsonSchema.maxProperties)
- [`@minContains`](./decorators.md#@TypeSpec.JsonSchema.minContains)
- [`@minProperties`](./decorators.md#@TypeSpec.JsonSchema.minProperties)
- [`@multipleOf`](./decorators.md#@TypeSpec.JsonSchema.multipleOf)
- [`@oneOf`](./decorators.md#@TypeSpec.JsonSchema.oneOf)
- [`@prefixItems`](./decorators.md#@TypeSpec.JsonSchema.prefixItems)
- [`@uniqueItems`](./decorators.md#@TypeSpec.JsonSchema.uniqueItems)

### Models

- [`Json`](./data-types.md#TypeSpec.JsonSchema.Json)

---

### Website Src Content Docs Docs Emitters Openapi3 Reference Index (`website/src/content/docs/docs/emitters/openapi3/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for emitting OpenAPI 3.0 and OpenAPI 3.1 from the TypeSpec REST protocol binding and converting OpenAPI3 to TypeSpec

## Install

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

```bash
npm install @typespec/openapi3
```

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

```bash
npm install --save-peer @typespec/openapi3
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

## TypeSpec.OpenAPI

### Decorators

- [`@oneOf`](./decorators.md#@TypeSpec.OpenAPI.oneOf)
- [`@useRef`](./decorators.md#@TypeSpec.OpenAPI.useRef)

---

### Website Src Content Docs Docs Emitters Protobuf Reference Index (`website/src/content/docs/docs/emitters/protobuf/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library and emitter for Protobuf (gRPC)

## Install

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

```bash
npm install @typespec/protobuf
```

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

```bash
npm install --save-peer @typespec/protobuf
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

## TypeSpec.Protobuf

### Decorators

- [`@field`](./decorators.md#@TypeSpec.Protobuf.field)
- [`@message`](./decorators.md#@TypeSpec.Protobuf.message)
- [`@package`](./decorators.md#@TypeSpec.Protobuf.package)
- [`@reserve`](./decorators.md#@TypeSpec.Protobuf.reserve)
- [`@service`](./decorators.md#@TypeSpec.Protobuf.service)
- [`@stream`](./decorators.md#@TypeSpec.Protobuf.stream)

### Models

- [`Extern`](./data-types.md#TypeSpec.Protobuf.Extern)
- [`LongRunningOperation`](./data-types.md#TypeSpec.Protobuf.LongRunningOperation)
- [`Map`](./data-types.md#TypeSpec.Protobuf.Map)
- [`PackageDetails`](./data-types.md#TypeSpec.Protobuf.PackageDetails)

## TypeSpec.Protobuf.WellKnown

### Models

- [`Any`](./data-types.md#TypeSpec.Protobuf.WellKnown.Any)
- [`Empty`](./data-types.md#TypeSpec.Protobuf.WellKnown.Empty)
- [`LatLng`](./data-types.md#TypeSpec.Protobuf.WellKnown.LatLng)
- [`Operation`](./data-types.md#TypeSpec.Protobuf.WellKnown.Operation)
- [`Timestamp`](./data-types.md#TypeSpec.Protobuf.WellKnown.Timestamp)

---

### Website Src Content Docs Docs Libraries Events Reference Index (`website/src/content/docs/docs/libraries/events/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library providing events bindings

## Install

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

```bash
npm install @typespec/events
```

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

```bash
npm install --save-peer @typespec/events
```

</TabItem>
</Tabs>

## TypeSpec.Events

### Decorators

- [`@contentType`](./decorators.md#@TypeSpec.Events.contentType)
- [`@data`](./decorators.md#@TypeSpec.Events.data)
- [`@events`](./decorators.md#@TypeSpec.Events.events)

---

### Website Src Content Docs Docs Libraries Http Server Js Reference Index (`website/src/content/docs/docs/libraries/http-server-js/reference/index.mdx`)

---
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 value="spec" label="In a spec" default>

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

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

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

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

---

### Website Src Content Docs Docs Libraries Http Reference Index (`website/src/content/docs/docs/libraries/http/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec HTTP protocol binding

## Install

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

```bash
npm install @typespec/http
```

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

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

</TabItem>
</Tabs>

## TypeSpec.Http

### Decorators

- [`@body`](./decorators.md#@TypeSpec.Http.body)
- [`@bodyIgnore`](./decorators.md#@TypeSpec.Http.bodyIgnore)
- [`@bodyRoot`](./decorators.md#@TypeSpec.Http.bodyRoot)
- [`@cookie`](./decorators.md#@TypeSpec.Http.cookie)
- [`@delete`](./decorators.md#@TypeSpec.Http.delete)
- [`@get`](./decorators.md#@TypeSpec.Http.get)
- [`@head`](./decorators.md#@TypeSpec.Http.head)
- [`@header`](./decorators.md#@TypeSpec.Http.header)
- [`@multipartBody`](./decorators.md#@TypeSpec.Http.multipartBody)
- [`@patch`](./decorators.md#@TypeSpec.Http.patch)
- [`@path`](./decorators.md#@TypeSpec.Http.path)
- [`@post`](./decorators.md#@TypeSpec.Http.post)
- [`@put`](./decorators.md#@TypeSpec.Http.put)
- [`@query`](./decorators.md#@TypeSpec.Http.query)
- [`@route`](./decorators.md#@TypeSpec.Http.route)
- [`@server`](./decorators.md#@TypeSpec.Http.server)
- [`@sharedRoute`](./decorators.md#@TypeSpec.Http.sharedRoute)
- [`@statusCode`](./decorators.md#@TypeSpec.Http.statusCode)
- [`@useAuth`](./decorators.md#@TypeSpec.Http.useAuth)

### Models

- [`AcceptedResponse`](./data-types.md#TypeSpec.Http.AcceptedResponse)
- [`ApiKeyAuth`](./data-types.md#TypeSpec.Http.ApiKeyAuth)
- [`AuthorizationCodeFlow`](./data-types.md#TypeSpec.Http.AuthorizationCodeFlow)
- [`BadRequestResponse`](./data-types.md#TypeSpec.Http.BadRequestResponse)
- [`BasicAuth`](./data-types.md#TypeSpec.Http.BasicAuth)
- [`BearerAuth`](./data-types.md#TypeSpec.Http.BearerAuth)
- [`Body`](./data-types.md#TypeSpec.Http.Body)
- [`ClientCredentialsFlow`](./data-types.md#TypeSpec.Http.ClientCredentialsFlow)
- [`ConflictResponse`](./data-types.md#TypeSpec.Http.ConflictResponse)
- [`CookieOptions`](./data-types.md#TypeSpec.Http.CookieOptions)
- [`CreatedResponse`](./data-types.md#TypeSpec.Http.CreatedResponse)
- [`File`](./data-types.md#TypeSpec.Http.File)
- [`ForbiddenResponse`](./data-types.md#TypeSpec.Http.ForbiddenResponse)
- [`HeaderOptions`](./data-types.md#TypeSpec.Http.HeaderOptions)
- [`HttpPart`](./data-types.md#TypeSpec.Http.HttpPart)
- [`HttpPartOptions`](./data-types.md#TypeSpec.Http.HttpPartOptions)
- [`ImplicitFlow`](./data-types.md#TypeSpec.Http.ImplicitFlow)
- [`Link`](./data-types.md#TypeSpec.Http.Link)
- [`LocationHeader`](./data-types.md#TypeSpec.Http.LocationHeader)
- [`MovedResponse`](./data-types.md#TypeSpec.Http.MovedResponse)
- [`NoAuth`](./data-types.md#TypeSpec.Http.NoAuth)
- [`NoContentResponse`](./data-types.md#TypeSpec.Http.NoContentResponse)
- [`NotFoundResponse`](./data-types.md#TypeSpec.Http.NotFoundResponse)
- [`NotModifiedResponse`](./data-types.md#TypeSpec.Http.NotModifiedResponse)
- [`OAuth2Auth`](./data-types.md#TypeSpec.Http.OAuth2Auth)
- [`OkResponse`](./data-types.md#TypeSpec.Http.OkResponse)
- [`OpenIdConnectAuth`](./data-types.md#TypeSpec.Http.OpenIdConnectAuth)
- [`PasswordFlow`](./data-types.md#TypeSpec.Http.PasswordFlow)
- [`PatchOptions`](./data-types.md#TypeSpec.Http.PatchOptions)
- [`PathOptions`](./data-types.md#TypeSpec.Http.PathOptions)
- [`PlainData`](./data-types.md#TypeSpec.Http.PlainData)
- [`QueryOptions`](./data-types.md#TypeSpec.Http.QueryOptions)
- [`Response`](./data-types.md#TypeSpec.Http.Response)
- [`UnauthorizedResponse`](./data-types.md#TypeSpec.Http.UnauthorizedResponse)

---

### Website Src Content Docs Docs Libraries Openapi Reference Index (`website/src/content/docs/docs/libraries/openapi/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library providing OpenAPI concepts

## Install

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

```bash
npm install @typespec/openapi
```

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

```bash
npm install --save-peer @typespec/openapi
```

</TabItem>
</Tabs>

## TypeSpec.OpenAPI

### Decorators

- [`@defaultResponse`](./decorators.md#@TypeSpec.OpenAPI.defaultResponse)
- [`@extension`](./decorators.md#@TypeSpec.OpenAPI.extension)
- [`@externalDocs`](./decorators.md#@TypeSpec.OpenAPI.externalDocs)
- [`@info`](./decorators.md#@TypeSpec.OpenAPI.info)
- [`@operationId`](./decorators.md#@TypeSpec.OpenAPI.operationId)
- [`@tagMetadata`](./decorators.md#@TypeSpec.OpenAPI.tagMetadata)

### Models

- [`AdditionalInfo`](./data-types.md#TypeSpec.OpenAPI.AdditionalInfo)
- [`Contact`](./data-types.md#TypeSpec.OpenAPI.Contact)
- [`ExternalDocs`](./data-types.md#TypeSpec.OpenAPI.ExternalDocs)
- [`License`](./data-types.md#TypeSpec.OpenAPI.License)
- [`TagMetadata`](./data-types.md#TypeSpec.OpenAPI.TagMetadata)
- [`TagMetadataWithName`](./data-types.md#TypeSpec.OpenAPI.TagMetadataWithName)

---

### Website Src Content Docs Docs Libraries Rest Reference Index (`website/src/content/docs/docs/libraries/rest/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec REST protocol binding

## Install

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

```bash
npm install @typespec/rest
```

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

```bash
npm install --save-peer @typespec/rest
```

</TabItem>
</Tabs>

## TypeSpec.Rest

### Decorators

- [`@action`](./decorators.md#@TypeSpec.Rest.action)
- [`@actionSeparator`](./decorators.md#@TypeSpec.Rest.actionSeparator)
- [`@autoRoute`](./decorators.md#@TypeSpec.Rest.autoRoute)
- [`@collectionAction`](./decorators.md#@TypeSpec.Rest.collectionAction)
- [`@copyResourceKeyParameters`](./decorators.md#@TypeSpec.Rest.copyResourceKeyParameters)
- [`@createsOrReplacesResource`](./decorators.md#@TypeSpec.Rest.createsOrReplacesResource)
- [`@createsOrUpdatesResource`](./decorators.md#@TypeSpec.Rest.createsOrUpdatesResource)
- [`@createsResource`](./decorators.md#@TypeSpec.Rest.createsResource)
- [`@deletesResource`](./decorators.md#@TypeSpec.Rest.deletesResource)
- [`@listsResource`](./decorators.md#@TypeSpec.Rest.listsResource)
- [`@parentResource`](./decorators.md#@TypeSpec.Rest.parentResource)
- [`@readsResource`](./decorators.md#@TypeSpec.Rest.readsResource)
- [`@resource`](./decorators.md#@TypeSpec.Rest.resource)
- [`@segment`](./decorators.md#@TypeSpec.Rest.segment)
- [`@segmentOf`](./decorators.md#@TypeSpec.Rest.segmentOf)
- [`@updatesResource`](./decorators.md#@TypeSpec.Rest.updatesResource)

## TypeSpec.Rest.Resource

### Interfaces

- [`ExtensionResourceCollectionOperations`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceCollectionOperations)
- [`ExtensionResourceCreate`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceCreate)
- [`ExtensionResourceCreateOrUpdate`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceCreateOrUpdate)
- [`ExtensionResourceDelete`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceDelete)
- [`ExtensionResourceInstanceOperations`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceInstanceOperations)
- [`ExtensionResourceList`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceList)
- [`ExtensionResourceOperations`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceOperations)
- [`ExtensionResourceRead`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceRead)
- [`ExtensionResourceUpdate`](./interfaces.md#TypeSpec.Rest.Resource.ExtensionResourceUpdate)
- [`ResourceCollectionOperations`](./interfaces.md#TypeSpec.Rest.Resource.ResourceCollectionOperations)
- [`ResourceCreate`](./interfaces.md#TypeSpec.Rest.Resource.ResourceCreate)
- [`ResourceCreateOrReplace`](./interfaces.md#TypeSpec.Rest.Resource.ResourceCreateOrReplace)
- [`ResourceCreateOrUpdate`](./interfaces.md#TypeSpec.Rest.Resource.ResourceCreateOrUpdate)
- [`ResourceDelete`](./interfaces.md#TypeSpec.Rest.Resource.ResourceDelete)
- [`ResourceInstanceOperations`](./interfaces.md#TypeSpec.Rest.Resource.ResourceInstanceOperations)
- [`ResourceList`](./interfaces.md#TypeSpec.Rest.Resource.ResourceList)
- [`ResourceOperations`](./interfaces.md#TypeSpec.Rest.Resource.ResourceOperations)
- [`ResourceRead`](./interfaces.md#TypeSpec.Rest.Resource.ResourceRead)
- [`ResourceUpdate`](./interfaces.md#TypeSpec.Rest.Resource.ResourceUpdate)
- [`SingletonResourceOperations`](./interfaces.md#TypeSpec.Rest.Resource.SingletonResourceOperations)
- [`SingletonResourceRead`](./interfaces.md#TypeSpec.Rest.Resource.SingletonResourceRead)
- [`SingletonResourceUpdate`](./interfaces.md#TypeSpec.Rest.Resource.SingletonResourceUpdate)

### Models

- [`CollectionWithNextLink`](./data-types.md#TypeSpec.Rest.Resource.CollectionWithNextLink)
- [`KeysOf`](./data-types.md#TypeSpec.Rest.Resource.KeysOf)
- [`ParentKeysOf`](./data-types.md#TypeSpec.Rest.Resource.ParentKeysOf)
- [`ResourceCollectionParameters`](./data-types.md#TypeSpec.Rest.Resource.ResourceCollectionParameters)
- [`ResourceCreatedResponse`](./data-types.md#TypeSpec.Rest.Resource.ResourceCreatedResponse)
- [`ResourceCreateModel`](./data-types.md#TypeSpec.Rest.Resource.ResourceCreateModel)
- [`ResourceCreateOrUpdateModel`](./data-types.md#TypeSpec.Rest.Resource.ResourceCreateOrUpdateModel)
- [`ResourceDeletedResponse`](./data-types.md#TypeSpec.Rest.Resource.ResourceDeletedResponse)
- [`ResourceError`](./data-types.md#TypeSpec.Rest.Resource.ResourceError)
- [`ResourceParameters`](./data-types.md#TypeSpec.Rest.Resource.ResourceParameters)

---

### Website Src Content Docs Docs Libraries Sse Reference Index (`website/src/content/docs/docs/libraries/sse/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library providing server sent events bindings

## Install

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

```bash
npm install @typespec/sse
```

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

```bash
npm install --save-peer @typespec/sse
```

</TabItem>
</Tabs>

## TypeSpec.SSE

### Decorators

- [`@terminalEvent`](./decorators.md#@TypeSpec.SSE.terminalEvent)

### Models

- [`SSEStream`](./data-types.md#TypeSpec.SSE.SSEStream)

---

### Website Src Content Docs Docs Libraries Streams Reference Index (`website/src/content/docs/docs/libraries/streams/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library providing stream bindings

## Install

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

```bash
npm install @typespec/streams
```

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

```bash
npm install --save-peer @typespec/streams
```

</TabItem>
</Tabs>

## TypeSpec.Streams

### Decorators

- [`@streamOf`](./decorators.md#@TypeSpec.Streams.streamOf)

### Models

- [`Stream`](./data-types.md#TypeSpec.Streams.Stream)

---

### Website Src Content Docs Docs Libraries Versioning Reference Index (`website/src/content/docs/docs/libraries/versioning/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for declaring and emitting versioned APIs

## Install

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

```bash
npm install @typespec/versioning
```

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

```bash
npm install --save-peer @typespec/versioning
```

</TabItem>
</Tabs>

## TypeSpec.Versioning

### Decorators

- [`@added`](./decorators.md#@TypeSpec.Versioning.added)
- [`@madeOptional`](./decorators.md#@TypeSpec.Versioning.madeOptional)
- [`@madeRequired`](./decorators.md#@TypeSpec.Versioning.madeRequired)
- [`@removed`](./decorators.md#@TypeSpec.Versioning.removed)
- [`@renamedFrom`](./decorators.md#@TypeSpec.Versioning.renamedFrom)
- [`@returnTypeChangedFrom`](./decorators.md#@TypeSpec.Versioning.returnTypeChangedFrom)
- [`@typeChangedFrom`](./decorators.md#@TypeSpec.Versioning.typeChangedFrom)
- [`@useDependency`](./decorators.md#@TypeSpec.Versioning.useDependency)
- [`@versioned`](./decorators.md#@TypeSpec.Versioning.versioned)

---

### Website Src Content Docs Docs Libraries Xml Reference Index (`website/src/content/docs/docs/libraries/xml/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library providing xml bindings

## Install

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

```bash
npm install @typespec/xml
```

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

```bash
npm install --save-peer @typespec/xml
```

</TabItem>
</Tabs>

## TypeSpec.Xml

### Decorators

- [`@attribute`](./decorators.md#@TypeSpec.Xml.attribute)
- [`@name`](./decorators.md#@TypeSpec.Xml.name)
- [`@ns`](./decorators.md#@TypeSpec.Xml.ns)
- [`@nsDeclarations`](./decorators.md#@TypeSpec.Xml.nsDeclarations)
- [`@unwrapped`](./decorators.md#@TypeSpec.Xml.unwrapped)

---

### Website Src Content Docs Docs Emitters Clients Http Client Csharp Reference Index (`website/src/content/docs/docs/emitters/clients/http-client-csharp/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for emitting Http Client libraries for C#.

## Install

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

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

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

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

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

## TypeSpec.HttpClient.CSharp

### Decorators

- [`@dynamicModel`](./decorators.md#@TypeSpec.HttpClient.CSharp.dynamicModel)

---

### Website Src Content Docs Docs Emitters Clients Http Client Java Reference Index (`website/src/content/docs/docs/emitters/clients/http-client-java/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for emitting Java client from the TypeSpec REST protocol binding

## Install

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

```bash
npm install @typespec/http-client-java
```

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

```bash
npm install --save-peer @typespec/http-client-java
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

---

### Website Src Content Docs Docs Emitters Clients Http Client Js Reference Index (`website/src/content/docs/docs/emitters/clients/http-client-js/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec library for emitting Http Client libraries for JavaScript/TypeScript

## Install

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

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

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

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

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

---

### Website Src Content Docs Docs Emitters Clients Http Client Python Reference Index (`website/src/content/docs/docs/emitters/clients/http-client-python/reference/index.mdx`)

---
title: Overview
sidebar_position: 0
toc_min_heading_level: 2
toc_max_heading_level: 3
---

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

TypeSpec emitter for Python SDKs

## Install

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

```bash
npm install @typespec/http-client-python
```

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

```bash
npm install --save-peer @typespec/http-client-python
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

---

### Website Src Content Docs Docs Emitters Servers Http Server Csharp Reference Index (`website/src/content/docs/docs/emitters/servers/http-server-csharp/reference/index.mdx`)

---
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)

---

### Website Src Content Docs Docs Emitters Servers Http Server Js Reference Index (`website/src/content/docs/docs/emitters/servers/http-server-js/reference/index.mdx`)

---
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)

---

### Packages Http Client Csharp Docs Decorators (`packages/http-client-csharp/docs/decorators.md`)

---
title: "Decorators"
description: "Decorators exported by @typespec/http-client-csharp"
toc_min_heading_level: 2
toc_max_heading_level: 3
---

## TypeSpec.HttpClient.CSharp

### `@dynamicModel` {#@TypeSpec.HttpClient.CSharp.dynamicModel}

Marks a model or namespace as dynamic, indicating it should generate dynamic model code.
Can be applied to Model or Namespace types.

```typespec
@TypeSpec.HttpClient.CSharp.dynamicModel
```

#### Target

`Model | Namespace`

#### Parameters

None

#### Examples

```tsp
@dynamicModel
model Pet {
  name: string;
  kind: string;
}

@dynamicModel
namespace PetStore {
  model Dog extends Pet {
    breed: string;
  }
}
```

---

### Packages Http Client Csharp Docs Emitter (`packages/http-client-csharp/docs/emitter.md`)

---
title: "Emitter usage"
---

## Emitter usage

1. Via the command line

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

2. Via the config

```yaml
emit:
  - "@typespec/http-client-csharp"
```

The config can be extended with options as follows:

```yaml
emit:
  - "@typespec/http-client-csharp"
options:
  "@typespec/http-client-csharp":
    option: value
```

## Emitter options

### `emitter-output-dir`

**Type:** `absolutePath`

Defines the emitter output directory. Defaults to `{output-dir}/@typespec/http-client-csharp`
See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory)

### `api-version`

**Type:** `string`

For TypeSpec files using the [`@versioned`](https://typespec.io/docs/libraries/versioning/reference/decorators/#@TypeSpec.Versioning.versioned) decorator, set this option to the version that should be used to generate against.

### `generate-protocol-methods`

**Type:** `boolean`

Set to `false` to skip generation of protocol methods. The default value is `true`.

### `generate-convenience-methods`

**Type:** `boolean`

Set to `false` to skip generation of convenience methods. The default value is `true`.

### `unreferenced-types-handling`

**Type:** `"removeOrInternalize" | "internalize" | "keepAll"`

Defines the strategy on how to handle unreferenced types. The default value is `removeOrInternalize`.

### `new-project`

**Type:** `boolean`

Set to `true` to overwrite the csproj if it already exists. The default value is `false`.

### `save-inputs`

**Type:** `boolean`

Set to `true` to save the `tspCodeModel.json` and `Configuration.json` files that are emitted and used as inputs to the generator. The default value is `false`.

### `package-name`

**Type:** `string`

Define the package name. If not specified, the first namespace defined in the TypeSpec is used as the package name.

### `debug`

**Type:** `boolean`

Set to `true` to automatically attempt to attach to a debugger when executing the C# generator. The default value is `false`.

### `logLevel`

**Type:** `"info" | "debug" | "verbose"`

Set the log level for which to collect traces. The default value is `info`.

### `disable-xml-docs`

**Type:** `boolean`

Set to `true` to disable XML documentation generation. The default value is `false`.

### `disable-roslyn-reduce`

**Type:** `boolean`

Set to `true` to skip the Roslyn reduce (simplification) post-processing step. This speeds up generation and is useful when iterating quickly. The default value is `false`.

### `generator-name`

**Type:** `string`

The name of the generator. By default this is set to `ScmCodeModelGenerator`. Generator authors can set this to the name of a generator that inherits from `ScmCodeModelGenerator`.

### `emitter-extension-path`

**Type:** `string`

Allows emitter authors to specify the path to a custom emitter package, allowing you to extend the emitter behavior. This should be set to `import.meta.url` if you are using a custom emitter.

### `plugins`

**Type:** `array`

Paths to generator plugin assemblies (DLLs) or directories containing plugin assemblies. Each plugin must contain a class that extends `GeneratorPlugin`. Paths may be absolute or relative to the resolved `emitter-output-dir`. For example, to load plugins that live in a `codegen` folder under the output directory:

```yaml
options:
  "@typespec/http-client-csharp":
    plugins:
      - "codegen/MyPlugin.dll" # file relative to emitter-output-dir
      - "codegen" # directory containing plugin assemblies
      - "/abs/path/to/MyPlugin.dll" # absolute path used as-is
```

See [Generator plugins](./plugins.md) for a walkthrough on authoring and using plugins.

### `license`

**Type:** `object`

License information for the generated client code.

### `sdk-context-options`

**Type:** `object`

The SDK context options that implement the `CreateSdkContextOptions` interface from the [`@azure-tools/typespec-client-generator-core`](https://www.npmjs.com/package/@azure-tools/typespec-client-generator-core) package to be used by the CSharp emitter.

---

### Packages Http Client Csharp Docs Plugins (`packages/http-client-csharp/docs/plugins.md`)

---
title: "Generator plugins"
---

## Generator plugins

Plugins are a lightweight way to customize the C# generator without authoring a full custom generator. A plugin can register additional visitors, rewriters, metadata references, or shared source directories that participate in the normal generation pipeline. This is useful when you want to tweak the generated output (for example, rename types, add attributes, or post-process models) while still using the built-in `ScmCodeModelGenerator`.

The generator discovers plugins in two ways:

1. **Automatically**, from the `dist` folder of any package listed in your project's `node_modules`.
2. **Explicitly**, from the paths supplied via the [`plugins`](./emitter.md#plugins) emitter option.

This document focuses on the `plugins` option, which lets emitter authors point the generator at one or more plugin assemblies (or directories/projects containing them).

## Authoring a plugin

A plugin is a C# class that extends `GeneratorPlugin` and overrides `Apply`. The base class is exported via [MEF](https://learn.microsoft.com/dotnet/framework/mef/) using `[InheritedExport]`, so any subclass is discovered automatically once its assembly is loaded — you do not need to add an `[Export]` attribute yourself.

```csharp
using Microsoft.TypeSpec.Generator;

public class MyPlugin : GeneratorPlugin
{
    public override void Apply(CodeModelGenerator generator)
    {
        // Register a custom visitor that transforms the output library.
        generator.AddVisitor(new MyLibraryVisitor());
    }
}
```

The `CodeModelGenerator` passed to `Apply` exposes the extension points a plugin can use, including:

- `AddVisitor(LibraryVisitor visitor)` — add a visitor that traverses and modifies the output library.
- `AddRewriter(LibraryRewriter rewriter)` — add a rewriter to transform generated members.
- `AddMetadataReference(MetadataReference reference)` — make additional assemblies available to the generated code.
- `AddSharedSourceDirectory(string sharedSourceDirectory)` — include a directory of shared source files.

A visitor lets you hook into specific parts of the output. For example, to transform every model:

```csharp
using Microsoft.TypeSpec.Generator;
using Microsoft.TypeSpec.Generator.Providers;

public class MyLibraryVisitor : LibraryVisitor
{
    protected override TypeProvider? VisitType(TypeProvider type)
    {
        // Inspect or modify the generated type here.
        return base.VisitType(type);
    }
}
```

### Plugin project file

Build your plugin as a class library that references the generator's published NuGet package. Referencing `Microsoft.TypeSpec.Generator.ClientModel` transitively brings in `Microsoft.TypeSpec.Generator`, which contains the `GeneratorPlugin` base class. Use the package version that matches the version of `@typespec/http-client-csharp` you are generating with. A minimal `.csproj` looks like this:

```xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.TypeSpec.Generator.ClientModel" Version="X.Y.Z" />
  </ItemGroup>

</Project>
```

## Using the `plugins` option

Once you have a plugin, point the emitter at it using the `plugins` option in `tspconfig.yaml`. Each entry is a path that may be **absolute** or **relative to the resolved `emitter-output-dir`**. A path can point to either:

- a **file** — a pre-built plugin assembly (`*.dll`), or
- a **directory** containing pre-built plugin assemblies (`*.dll`) or a `.csproj` — when a `.csproj` is present the generator builds it (`dotnet build -c Release`) before loading the resulting assembly.

For example, to load plugins that live in a `codegen` folder under the output directory:

```yaml
emit:
  - "@typespec/http-client-csharp"
options:
  "@typespec/http-client-csharp":
    plugins:
      - "codegen/MyPlugin.dll" # file relative to emitter-output-dir
      - "codegen" # directory containing plugin assemblies
      - "/abs/path/to/MyPlugin.dll" # absolute path used as-is
```

Notes:

- Absolute paths are used as-is; relative paths are anchored to the resolved `emitter-output-dir`.
- When a directory contains a `.csproj`, it is built automatically; otherwise the directory is scanned for pre-built `*.dll` files.
- Plugins loaded via the `plugins` option are applied in addition to any plugins discovered through `node_modules`.

After the assemblies are loaded, every discovered `GeneratorPlugin` has its `Apply` method invoked on the selected generator before generation runs, so all of your registered visitors, rewriters, and references take effect.

---

### Packages Http Server Csharp Docs Emitter (`packages/http-server-csharp/docs/emitter.md`)

---
title: "Emitter usage"
---

# Emitter 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 files, setup code, 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.

---

### Packages Http Server Csharp Docs Usage (`packages/http-server-csharp/docs/usage.md`)

---
title: Generated C-Sharp Overview
---

# Generated C-Sharp Overview

## 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) 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.

## 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

---

### Packages Spector Docs Decorators (`packages/spector/docs/decorators.md`)

## Spector decorators

### `@scenarioService`

Decorator setting up the boilerplate for specs service namespace. Will automatically set:

- `@service{title: '<namespace>', value: '1.0.0'}` using the namespace as a value
- `@server` to `localhost:3000`
- `@route` using the parameter passed.

Usage:

```tsp
@scenarioSpec("/my-spec")
namespace MySpec;
```

### `@scenario`

Mark an operation, interface or namespace as a scenario. Optionally can provide the name of the scenario.

### `@scenarioDoc`

Specify how to implement this scenario. Value is markdown. Differ from @doc which describe the scenario to the end user.

---

### Packages Spector Docs Using Spector (`packages/spector/docs/using-spector.md`)

# Using spector

Install `spector` CLI globally or as a local dependency:

- **Globally**: run `npm install @typespec/spector`. You can then use `tsp-spector` as a CLI tool.
- **Locally**: run `npm install @typespec/spector` which should add the dependency to package.json. You can then use `tsp-spector` with `npx tsp-spector`.

**NOTE** With local install you'll need to prefix `tsp-spector` with `npx`(unless commands are written directly as npm scripts)

## Test against scenarios

### Spector Config

Spector supports a config file where you can configure scenarios that are not supported by your generator.

Create a `spector-config.yaml` file.

```yaml
# List of unsupported scenarios
unsupportedScenarios:
  - Foo_Bar
```

### Run mock api server

```bash
# Minimal
tsp-spector serve ./path/to/scenarios

# Change the port
tsp-spector serve ./path/to/scenarios --port 1234

# Specify where the coverage file should go
tsp-spector serve ./path/to/scenarios --coverageFile ./path/to/spector-coverage.json
```

> [!NOTE]
> The server always binds to the loopback interface (`127.0.0.1`), so it is only reachable from the local host and is not exposed to other machines on the network.

Alternative to start in background

```bash
tsp-spector server start ./path/to/scenarios # Takes the same arguments as serve
```

### Stop running server

```bash
tsp-spector server stop             # Stop at the default port
tsp-spector server stop --port 1234 # If started the server at another port
```

### Validate and merge coverage

```bash
# Minimal
tsp-spector check-coverage ./path/to/scenarios

# Path to tsp-spector config file for generator
tsp-spector check-coverage ./path/to/scenarios --configFile ./spector-config.yaml

# In case where there was multiple serve instance each creating their own coverage file
tsp-spector check-coverage ./path/to/scenarios --coverageFiles ./path/to/*-coverage.json --coverageFiles ./other/to/*-coverage.json

# Specify where the merged coverage file should go
tsp-spector check-coverage ./path/to/scenarios --mergedCoverageFile ./path/to/spector-final-coverage.json
```

### Upload coverage

Upload the coverage. Upload from the `main` branch. DO NOT upload on PR this WILL override the latest index.

```bash
# Minimal
tsp-spector upload-coverage --generatorName typescript --version=0.1.0

# Specify Coverage file
tsp-spector upload-coverage --generatorName typescript --version=0.1.0 --coverageFile ./path/to/spector-final-coverage.json
```

Options:

- `--storageAccountName`: Name of the storage account to publish coverage. Use `typespec` for Spector/Azure Spector dashboard.
- `--generatorName`: Name of the generator. Must be one of `"@typespec/http-client-python", "@typespec/http-client-csharp", "@azure-tools/typespec-ts-rlc", "@azure-tools/typespec-ts-modular", "@typespec/http-client-js", "@typespec/http-client-java"`.
- `--generatorVersion`: Version of the generator
- `--coverageFile`: Path to the coverage file

#### Upload in azure devops

**This is applicable in the azure-sdk/internal ado project only.**

Add the following step

```yaml
- task: AzureCLI@2
  displayName: Upload scenario coverage
  inputs:
    azureSubscription: "Typespec Storage"
    scriptType: "bash"
    scriptLocation: "inlineScript"
    inlineScript: `tsp-spector upload-coverage --storageAccountName typespec --containerName coverages --generatorMode standard  ... FILL options fitting your generator here as described above...`
```

---

### Packages Spector Docs Writing Mock Apis (`packages/spector/docs/writing-mock-apis.md`)

# Writing mock apis

1. Create a `mockapi.ts` file next to the `main.tsp` of the scenario
2. Create and export a variable called `Scenarios` with a `Record<string, ScenarioMockApi>` type
3. For each of the scenario assign a new property to the `Scenarios` variable. The value use one of the following:
   - `passOnSuccess`: This will take one or multiple routes and will only pass teh scenario if all the routes gets called with a 2xx success code.

## Example

```ts
import { passOnSuccess, mockapi } from "@typespec/spec-api";
import { ScenarioMockApi } from "@typespec/spec-api";

export const Scenarios: Record<string, ScenarioMockApi> = {};

Scenarios.Hello_world = passOnSuccess(
  mockapi.get("/hello/world", () => {
    return {
      status: 200,
      body: {
        contentType: "application/json",
        rawContent: `"Hello World!"`,
      },
    };
  }),
);
```

## How to build response

Return the response object. [See type](../../spec-api/src/types.ts)

```ts
// Minimum requirement is the status code.
return {
  status: 200,
};
```

### Return a body

```ts
// Return json
return {
  status: 200,
  body: json({ foo: 123 }),
};

// Return raw content
return {
  status: 200,
  body: {
    contentType: "application/text",
    rawContent: "foobar",
  },
};
```

### Return headers

```ts
// Return json
return {
  status: 200,
  headers: {
      MyHeader: "value-1"
      MyHeaderOther: req.headers.MyRequestHeader
  }
};

```

## How to validate the request:

All built-in validation tools can be accessed using `req.expect.`

### Validate the body

- With `req.expect.bodyEquals`

This will do a deep equals of the body to make sure it match.

```ts
app.post("/example", "Example", (req) => {
  req.bodyEquals({ foo: "123", bar: "456" });
});
```

- With `req.expect.rawBodyEquals`

This will compare the raw body sent.

```ts
app.post("/example", "Example", (req) => {
  req.rawBodyEquals('"foo"');
});
```

### Custom validation

You can do any kind of validation accessing the `req: MockRequest` object and deciding to return a different response in some cases.
You can also always `throw` a `ValidationError`

Example:

```ts
app.post("/example", "Example", (req) => {
  if (req.headers.MyCustomHeader.startsWith("x-foo")) {
    throw new ValidationError(
      "MyCustomHeader shouldn't start with x-foo",
      null,
      req.headers.MyCustomHeader,
    );
  }
});
```

---

### Packages Spector Docs Writing Scenario Spec (`packages/spector/docs/writing-scenario-spec.md`)

## Defining scenario

The goal of the testserver is to define scenarios that needs to be supported in client generators. This means to have a meaningful coverage we need scenarios to:

- have a specific behavior that is meant to be tested
  - ❌ DO NOT use the same scenario for testing multiple things.
- have a meaningful name that can be used in a compatibility table to see what a given generator support(e.g. `get_string`)
- a description of what the scenario is validating(e.g. `"Support passing a simple string as JSON"`)
- have a good description on what the client is expecting to generate/receive/send(e.g `Validate that this operation returns a JSON string that match "abc"`)
  - ✅ DO describe how to validate that this scenario is working from the client point of view

When naming scenario always think about what would it look like in the [compatibility table](#compatibility-table) and would that name be meaningful to someone looking to see what is supported.

```cadl
import "@typespec/spector";

@scenarioService("/strings")
namespace String;

@scenario("get_string")
@doc("Support passing a simple string as JSON")
@scenarioDoc("In this scenario the Client should expect a string matching 'abc' to be returned.")
@get
@route("/simple")
op returnString(): string;
```

Decorators that should be provided in this test library `@typespec/spector`:

- `@scenario`: Specify that this operation, interface or namespace is a scenario. Optionally take a scenario name otherwise default to the namespace name + operation/interface name
- `@scenarioDoc`: Specify how to implement this scenario. Differ from `@doc` which describe the scenario to the end user.
- `@supportedBy`: Specify if something is supported only by some kind of SDK. Option: `arm`, `dpg`. By default everything.

## Compatibility table

With all this information, a detailed compatibility table should be able to be produced by compiling each one of the scenarios and extracting the cases. Providing something like

| Scenario                     | CSharp | Python | Go  | Java | TS/JS |
| ---------------------------- | ------ | ------ | --- | ---- | ----- |
| Vanilla                      |
| `get_string`                 | ✅     | ✅     | ✅  | ✅   | ✅    |
| `put_string`                 | ✅     | ✅     | ✅  | ✅   | ✅    |
| Azure                        |
| `pageable_nextLink`          | ✅     | ✅     | ✅  | ✅   | ✅    |
| `pageable_continuationToken` | ❌     | ✅     | ✅  | ✅   | ✅    |

## Writing the mock api

Each scenario should be accompanied by a mock api. See [writing a mock api docs](./writing-mock-apis.md)

---

### Packages Http Client Csharp .Tspd Docs Customization (`packages/http-client-csharp/.tspd/docs/customization.md`)

# Customizing the generated code

## Before You Customize

Before customizing generated code, consider whether your change should be made in TypeSpec (`client.tsp`) instead. TypeSpec customizations allow you to apply changes to multiple languages at once, are more discoverable for other languages, and live right near the spec bringing us more to a single source of truth. See the [TypeSpec Client Customizations Reference](https://github.com/Azure/azure-sdk-tools/blob/main/eng/common/knowledge/customizing-client-tsp.md) for available decorators like `@@clientName`, `@@access`, etc.

Use C# code customizations (partial classes) when TypeSpec cannot express the behavior you need.

## Optional nullable model properties

For a TypeSpec property such as `feature?: Feature | null`, generated model classes distinguish an omitted property from an explicitly assigned `null` during JSON serialization. Leaving the property untouched omits it; assigning `null` writes `"feature": null`; assigning a value writes that value. Reading JSON preserves the same distinction when the model is serialized again, including nested models and wire-format serialization.

For nullable additional-property values, such as `Record<string | null>`, JSON null entries are retained in `AdditionalProperties` and included when the model is serialized again, including in wire format.

XML serialization omits null optional properties, including collections, rather than emitting explicit-null elements. Writing XML does not change their JSON presence state.

Presence tracking does not change the public property type or constructor/model-factory signatures. Defaulted constructor and model-factory arguments retain their existing behavior: a scalar `null` argument is treated as omitted, since C# cannot distinguish an omitted argument from an explicitly supplied default value. Model factories also retain their existing collection initialization behavior, which can materialize a defaulted list argument as an empty list. To write explicit null for a writable property, assign the property after construction.

A handwritten property or field that replaces a generated member (including a `[CodeGenMember]` replacement) retains its existing customization behavior; the generator cannot observe assignments inside a handwritten setter. There is no presence-tracking opt-in for replacement members. Models customized as readonly structs also retain their existing constructor-only behavior, because readonly structs cannot contain the mutable backing fields and presence flags used by generated classes. Keep the generated class property when its omitted/null distinction is needed. Similarly, plugins that replace generated property bodies or serialization methods must preserve the tracking behavior themselves rather than relying on a replacement auto-property.

## Make a model internal

Define a class with the same namespace and name as generated model and use the desired accessibility.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model { }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    internal partial class Model { }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
namespace Azure.Service.Models
{
-    public partial class Model { }
+    internal partial class Model { }
}
```

</details>

## Rename a model class

Define a class with a desired name and mark it with `[CodeGenType("OriginalName")]`

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model { }
}
```

**Add customized model (NewModelClassName.cs)**

```C#
namespace Azure.Service.Models
{
    [CodeGenType("Model")]
    public partial class NewModelClassName { }
}
```

**Generated code after (Generated/Models/NewModelClassName.cs):**

```diff
namespace Azure.Service.Models
{
-    public partial class Model { }
+    public partial class NewModelClassName { }
}
```

</details>

## Change a model or client namespace

Define a class with a desired namespace and mark it with `[CodeGenType("OriginalName")]`.

The same works for a client, if marked with `[CodeGenType("ClientName")]`.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model { }
}
```

**Add customized model (NewModelClassName.cs)**

```C#
namespace Azure.Service
{
    [CodeGenType("Model")]
    public partial class Model { }
}
```

**Generated code after (Generated/Models/NewModelClassName.cs):**

```diff
- namespace Azure.Service.Models
+ namespace Azure.Service
{
    public partial class Model { }
}
```

</details>

## Make model property internal

Define a class with a property matching a generated property name but with desired accessibility.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public string Property { get; }
    }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        internal string Property { get; }
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
namespace Azure.Service.Models
{
    public partial class Model
    {
-        public string Property { get; }
    }
}
```

</details>

## Rename a model property

Define a partial class with a new property name and mark it with `[CodeGenMember("OriginalName")]` attribute.

**NOTE:** you can also change a property to a field using this mapping.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public string Property { get; }
    }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        [CodeGenMember("Property")]
        public string RenamedProperty { get; }
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
namespace Azure.Service.Models
{
    public partial class Model
    {
-        public string Property { get; }
+        // All original Property usages would reference a RenamedProperty
    }
}
```

</details>

## Change a model property type

:warning:

**NOTE: This is supported for a narrow set of cases where the underlying serialized type doesn't change**

Scenarios that would work:

1. String <-> TimeSpan (both represented as string in JSON)
2. Float <-> Int (both are numbers)
3. String <-> Enums (both strings)
4. String -> Uri
5. String -> Guid (both strings)

Won't work:

1. String <-> Bool (different json type)
2. Changing model kinds

If you think you have a valid re-mapping scenario that's not supported file an issue.

:warning:

Define a property with different type than the generated one.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public string Property { get; }
    }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public DateTime Property { get; }
    }
}
```

**Generated code after (Generated/Models/Model.Serializer.cs):**

```diff
namespace Azure.Service.Models
{
    public partial class Model
    {
-        public string Property { get; }
+        // Serialization code now reads and writes DateTime value instead of string
    }
}
```

</details>

## Preserve raw Json value of a property

Use the [Change a model property type](#Change-a-model-property-type) approach to change property type to `JsonElement`.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public string Property { get; }
    }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public JsonElement Property { get; }
    }
}
```

**Generated code after (Generated/Models/Model.Serializer.cs):**

```diff
namespace Azure.Service.Models
{
    public partial class Model
    {
-        public string Property { get; }
+        // Serialization code now reads and writes JsonElement value instead of string
    }
}
```

</details>

## Changing member doc comment

Redefine a member in partial class with a new doc comment.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        /// Subpar doc comment
        public string Property { get; }
    }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        /// Great doc comment
        public string Property { get; }
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
namespace Azure.Service.Models
{
    public partial class Model
    {
-        /// Subpar doc comment
-        public string Property { get; }
    }
}
```

</details>

## Customize serialization/deserialization methods

Changing how a property serializes or deserializes is done by `CodeGenSerialization` attribute. This attribute can be applied to a class or struct with a property name to change the serialization/deserialization method of the property.

### Change the serialized name of a property

If you want to change the property name that serializes into the JSON or deserializes from the JSON, you could define your own partial class with the `CodeGenMemberSerialization` attribute.

<details>

For instance, we have a model class `Cat` with property `Name` and `Color`:

**Generated code before:**

```C#
// Generated/Models/Cat.cs
namespace Azure.Service.Models
{
    public partial class Cat
    {
        /* omit the ctors for brevity */
        public string Name { get; set; }
        public string Color { get; set; }
    }
}
```

**Add customized model:**

```C#
// Cat.cs
namespace Azure.Service.Models
{
    [CodeGenSerialization(nameof(Name), "catName")] // add the property name, and the new serialized name
    public partial class Cat
    {
    }
}
```

**Generated code after:**

```diff
// Generated/Models/Cat.cs - no change

// Generated/Models/Cat.Serialization.cs
namespace Azure.Service.Models
{
    public partial class Cat : IUtf8JsonSerializable
    {
        void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
-           writer.WritePropertyName("name"u8);
+           writer.WritePropertyName("catName"u8);
            writer.WriteStringValue(Name);
            writer.WritePropertyName("color"u8);
            writer.WriteStringValue(Color);
            writer.WriteEndObject();
        }

        internal static Cat DeserializeCat(JsonElement element)
        {
            if (element.ValueKind == JsonValueKind.Null)
            {
                return null;
            }
            string name = default;
            Optional<string> color = default;
            foreach (var property in element.EnumerateObject())
            {
-               if (property.NameEquals("name"u8))
+               if (property.NameEquals("catName"u8))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("color"u8))
                {
                    color = property.Value.GetString();
                    continue;
                }
            }
            return new Cat(name, color);
        }
    }
}
```

### Change the hierarchy of a property in the serialized JSON

If you want to change the layer of the property in the json, you can add all the elements in the json path of your property to the attribute using an array, the generator will generate the property into the JSON in the correct hierarchy.

**NOTE: Introducing extra layers in serialized JSON only works for MPG and HLC models, does not work for DPG models.**

For instance, we want to move `Name` property in the model `Cat` to make it serialized under property `properties` and rename to `catName`.

**Generated code before:**

```C#
// Generated/Models/Cat.cs
namespace Azure.Service.Models
{
    public partial class Cat
    {
        /* omit the ctors for brevity */
        public string Name { get; set; }
        public string Color { get; set; }
    }
}

// Generated/Models/Cat.Serialization.cs
namespace Azure.Service.Models
{
    public partial class Cat : IUtf8JsonSerializable
    {
        void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("name"u8);
            writer.WriteStringValue(Name);
            writer.WritePropertyName("color"u8);
            writer.WriteStringValue(Color);
            writer.WriteEndObject();
        }

        internal static Cat DeserializeCat(JsonElement element)
        {
            if (element.ValueKind == JsonValueKind.Null)
            {
                return null;
            }
            string name = default;
            Optional<string> color = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("name"u8))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("color"u8))
                {
                    color = property.Value.GetString();
                    continue;
                }
            }
            return new Cat(name, color);
        }
    }
}
```

**Add customized model:**

```C#
// Cat.cs
namespace Azure.Service.Models
{
    [CodeGenSerialization(nameof(Name), new string[] { "properties", "catName" })]
    public partial class Cat
    {
    }
}
```

**Generated code after:**

```
/* Detailed source-code truncated for AI context efficiency. */
```

</details>

### Change the implementation of serialization/deserialization method of a property

If you want to change the implementation of serialization/deserialization method of a property, you could define your own hook methods and assign them to the `CodeGenSerialization` attribute.

The custom serialization method for this property is assigned by the `SerializationValueHook` property of the `CodeGenSerialization` attribute, and the custom deserialization method for this property is assigned by the `DeserializationValueHook` property of the `CodeGenSerialization` attribute.

The `SerializationValueHook` and `DeserializationValueHook` here are hook method names, and these methods should have the signature as below:

```C#
// serialization hook and serialization value hook
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void SerializationMethodHook(Utf8JsonWriter writer)
{
    // write your own serialization logic here
}

// deserialization hook for required property
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void DeserializeSizeProperty(JsonProperty property, ref TypeOfTheProperty name)
{
    // write your own deserialization logic here
}
// deserialization hook for optional property
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void DeserializeSizeProperty(JsonProperty property, ref Optional<TypeOfTheProperty> name)
{
    // write your own deserialization logic here
}
```

Please use the `nameof` expression to avoid typo in the attribute. Also you could leave both the serialization value hook unassigned if you do not want to change the serialization logic, similar you could leave deserialization hook unassigned if you do not want to change the deserialization logic.

The `[MethodImpl(MethodImplOptions.AggressiveInlining)]` attribute is recommended for your hook methods to get optimized performance.

Please note that the generator will not check the signature of the hook methods you assigned to the attribute, therefore if the signature is not compatible, the generated library might not compile.

<details>

For instance, we have a model class `Cat` with property `Name` and `Color`, and we would like to change the way how `Name` property is serialized and deserialized.

**Generated code before:**

```C#
// Generated/Models/Cat.cs
namespace Azure.Service.Models
{
    public partial class Cat
    {
        /* omit the ctors for brevity */
        public string Name { get; set; }
        public string Color { get; set; }
    }
}

// Generated/Models/Cat.Serialization.cs
namespace Azure.Service.Models
{
    public partial class Cat : IUtf8JsonSerializable
    {
        void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("name"u8);
            writer.WriteStringValue(Name);
            writer.WritePropertyName("color"u8);
            writer.WriteStringValue(Color);
            writer.WriteEndObject();
        }

        internal static Cat DeserializeCat(JsonElement element)
        {
            if (element.ValueKind == JsonValueKind.Null)
            {
                return null;
            }
            string name = default;
            Optional<string> color = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("name"u8))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("color"u8))
                {
                    color = property.Value.GetString();
                    continue;
                }
            }
            return new Cat(name, color);
        }
    }
}
```

**Add customized model:**

```C#
// Cat.cs
namespace Azure.Service.Models
{
    [CodeGenSerialization(nameof(Name), SerializationValueHook = nameof(SerializeNameValue), DeserializationValue = nameof(DeserializeNameValue))]
    public partial class Cat
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private void SerializeNameValue(Utf8JsonWriter writer)
        {
            // this is the logic we would like to have for the value serialization
            writer.WriteStringValue(Name.ToUpper());
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static void DeserializeNameValue(JsonProperty property, ref string name) // the type here is string since name is required
        {
            // this is the logic we would like to have for the value deserialization
            name = property.Value.GetString().ToLower();
        }
    }
}
```

**Generated code after:**

```diff
// Generated/Models/Cat.cs - no change

// Generated/Models/Cat.Serialization.cs
namespace Azure.Service.Models
{
    public partial class Cat : IUtf8JsonSerializable
    {
        void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("name"u8);
-           writer.WriteStringValue(Name);
+           SerializeNameValue(writer);
            if (Optional.IsDefined(Color))
            {
                writer.WritePropertyName("color"u8);
                writer.WriteStringValue(Color);
            }
            writer.WriteEndObject();
        }

        internal static Cat DeserializeCat(JsonElement element)
        {
            if (element.ValueKind == JsonValueKind.Null)
            {
                return null;
            }
            string name = default;
            Optional<string> color = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("name"u8))
                {
-                   meow = property.Value.GetString();
+                   DeserializeNameValue(property, ref name);
                    continue;
                }
                if (property.NameEquals("color"u8))
                {
                    color = property.Value.GetString();
                    continue;
                }
            }
            return new Cat(name, color, size);
        }
    }
}
```

</details>

### Add a new property to the model with serialization/deserialization

If you want to add a new property to the model and also add the property into the serialization/deserialization methods, you could also use the `CodeGenSerialization` attribute to change its default serialized name, and serialization/deserialization methods.

<details>

**Generated code before:**

```C#
// Generated/Models/Cat.cs
namespace Azure.Service.Models
{
    public partial class Cat
    {
        /* omit the ctors for brevity */
        public string Name { get; set; }
        public string Color { get; set; }
    }
}

// Generated/Models/Cat.Serialization.cs
namespace Azure.Service.Models
{
    public partial class Cat : IUtf8JsonSerializable
    {
        void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("name"u8);
            writer.WriteStringValue(Name);
            writer.WritePropertyName("color"u8);
            writer.WriteStringValue(Color);
            writer.WriteEndObject();
        }

        internal static Cat DeserializeCat(JsonElement element)
        {
            if (element.ValueKind == JsonValueKind.Null)
            {
                return null;
            }
            string name = default;
            Optional<string> color = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("name"u8))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("color"u8))
                {
                    color = property.Value.GetString();
                    continue;
                }
            }
            return new Cat(name, color);
        }
    }
}
```

**Add customized model:**

```C#
[CodeGenSerialization(nameof(Size), "size")]
public partial class Cat
{
    public int? Size { get; set; }
}
```

**Generated code after:**

```
/* Detailed source-code truncated for AI context efficiency. */
```

You could also add the `CodeGenSerialization` attribute to the property to have your own serialization/deserialization logic of the new property. You might have to do this if the type of your new property is an object type or any type that our generator does not natively support.

**NOTE: Adding property to serialization/deserialization methods currently only works for DPG.**

</details>

#### Replace the entire serialization/deserialization method

If you want to replace the entire serialization/deserialization method, please use the [Replace any generated member](#replace-any-generated-member) approach to replace serialization/deserialization method with a custom implementation.

<details>

**Generated code before:**

```C#
// Generated/Models/Cat.Serialization.cs
namespace Azure.Service.Models
{
    public partial class Cat
    {
        void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("name"u8);
            writer.WriteStringValue(Name);
            if (Optional.IsDefined(Color))
            {
                writer.WritePropertyName("color"u8);
                writer.WriteStringValue(Color);
            }
            writer.WriteEndObject();
        }

        internal static Cat DeserializeCat(JsonElement element)
        {
            string color = default;
            string name = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("color"u8))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    color = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("name"u8))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    name = property.Value.GetString();
                    continue;
                }
            }
            return new Cat(id, name);
        }
    }
}
```

**Add customized model:**

```C#
// Cat.cs
namespace Azure.Service.Models
{
    public partial class Cat
    {
        // currently we have to use a full name to ensure this could be replaced
        void global:Azure.Core.IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("name"u8);
            writer.WriteStringValue(Name);
            // WORKAROUND: server never needs color, remove it in the customization code
            writer.WriteEndObject();
        }

        internal static Cat DeserializeCat(JsonElement element)
        {
            string color = default;
            string name = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("name"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    name = property.Value.GetString();
                    continue;
                }
            }
            // WORKAROUND: server never sends color, default to black
            color = "black";
            return new Cat(name, color);
        }
    }
}
```

**Generated code after:**

Generated code won't contain the `IUtf8JsonSerializable.Write` or `DeserializeCat` method and the custom one would be used for deserialization.

</details>

## Renaming an enum

Redefine an enum with a new name and all the members mark it with `[CodeGenType("OriginEnumName")]`.

**NOTE: because enums can't be partial all values have to be copied**

<details>

**Generated code before (Generated/Models/Colors.cs):**

```C#
namespace Azure.Service.Models
{
    public enum Colors
    {
        Red,
        Green,
        Blue
    }
}
```

**Add customized model (WallColors.cs)**

```C#
namespace Azure.Service.Models
{
    [CodeGenType("Colors")]
    public enum WallColors
    {
        Red,
        Green,
        Blue
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
-namespace Azure.Service.Models
-{
-    public enum Colors
-    {
-        Red,
-        Green,
-        Blue
-    }
-}
+// Serialization code uses the new WallColors type name
```

</details>

### Renaming an enum member

Redefine an enum with the same name and all the members, mark renamed member with `[CodeGenMember("OriginEnumMemberName")]`.

**NOTE: because enums can't be partial all values have to be copied but only the ones being renamed should be marked with an attributes**

<details>

**Generated code before (Generated/Models/Colors.cs):**

```C#
namespace Azure.Service.Models
{
    public enum Colors
    {
        Red,
        Green,
        Blue
    }
}
```

**Add customized model (Colors.cs)**

```C#
namespace Azure.Service.Models
{
    public enum Colors
    {
        Red,
        Green,
        [CodeGenMember("Blue")]
        SkyBlue
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
-namespace Azure.Service.Models
-{
-    public enum Colors
-    {
-        Red,
-        Green,
-        Blue
-    }
-}
+// Serialization code uses the new SkyBlue member name
```

</details>

## Changing an enum to an extensible enum

Redefine an enum into an extensible enum by creating an empty struct with the same name as original enum.

<details>

**Generated code before (Generated/Models/Colors.cs):**

```C#
namespace Azure.Service.Models
{
    public enum Colors
    {
        Red,
        Green
    }
}
```

**Add customized model (Colors.cs)**

```C#
namespace Azure.Service.Models
{
    public partial struct Colors
    {
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
namespace Azure.Service.Models
{
-    public enum Colors
-    {
-        Red,
-        Green
-    }
+    public readonly partial struct Colors : IEquatable<Colors>
+    {
+        private readonly string _value;

+        public Colors(string value)
+        {
+            _value = value ?? throw new ArgumentNullException(nameof(value));
+        }

+        private const string Red = "red";
+        private const string Green = "green";

+        public static Colors Red { get; } = new Colors(Red);
+        public static Colors Green { get; } = new Colors(Green);
+        public static bool operator ==(Colors left, Colors right) => left.Equals(right);
         ...
}
```

</details>

## Make a client internal

Define a class with the same namespace and name as generated client and use the desired accessibility.

<details>

**Generated code before (Generated/Operations/ServiceClient.cs):**

```C#
namespace Azure.Service.Operations
{
    public partial class ServiceClient { }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Operations
{
    internal partial class ServiceClient { }
}
```

**Generated code after (Generated/Operations/ServiceClient.cs):**

```diff
namespace Azure.Service.Operations
{
-    public partial class ServiceClient { }
+    internal partial class ServiceClient { }
}
```

</details>

## Rename a client

Define a partial client class with a new name and mark it with `[CodeGenType("OriginalName")]`

<details>

**Generated code before (Generated/Operations/ServiceClient.cs):**

```C#
namespace Azure.Service.Operations
{
    public partial class ServiceClient {}
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Operations
{
    [CodeGenType("ServiceClient")]
    public partial class TableClient { }
}
```

**Generated code after (Generated/Operations/ServiceClient.cs):**

```diff
namespace Azure.Service.Operations
{
-    public partial class ServiceClient { }
+    public partial class TableClient { }
}
```

</details>

## Customize a generated client method's signature

Declare a `partial` method (without a body) on the generated client class with the same name and parameter types as a generated protocol or convenience method. The generator emits a matching partial implementation, taking the modifiers and parameter names from your declaration while keeping its generated body.

This applies specifically to **client methods** (protocol and convenience methods on the generated `*Client` class). Other generated members (model constructors, model serialization methods, model factories, etc.) should be customized using `[CodeGenSuppress]` + a hand-written replacement, or one of the other techniques in this document.

Use this when you want to keep the generated body but tweak the surface — typically:

- Tighten the access modifier (`public` → `internal`).
- Add `virtual` / `override` / `new` modifiers.
- Rename a parameter to something more idiomatic.

This is preferred over `[CodeGenSuppress]` + a hand-written replacement when the only thing you want to change is the signature, because you stay in lock-step with the generated body — future regenerations automatically pick up changes (new optional parameters, body changes from spec edits, etc.).

### What is supported

- **Modifier changes** (access modifier, `virtual`, `override`, `new`, `unsafe`).
- **Parameter renames.** The generator clones each parameter with the customer-chosen name while preserving all internal metadata (parameter location, wire info, spread source, validation, …) so the generated body keeps compiling.
- Both protocol method overloads and convenience method overloads (sync and async) on the generated client. Each overload must be customized independently.

### What is NOT supported

- **Renaming the method itself.** Matching is by `(method name, ordered parameter type list)`. To rename, use `[CodeGenSuppress]` + a hand-written method that delegates to the underlying request/pipeline machinery.
- **Changing parameter types.** The parameter type list must match the generated signature exactly (matched by type name). Replacing a parameter type with a different type — even an implicitly convertible one — will simply fail to match and the partial decl will be ignored. To project a different type, use `[CodeGenSuppress]` + a hand-written wrapper that converts and forwards.
- **Adding/removing/reordering parameters.** The parameter type list must match the generated signature exactly. To restructure, use `[CodeGenSuppress]`.
- **Default values on the partial implementation.** C# requires partial method implementations to have all parameters required, so any default values on your partial declaration are stripped on the generated impl. Callers still see the defaults from your declaration in custom code.
- **Non-client members** (models, serialization methods, model factories). Use `[CodeGenSuppress]` for these.

<details>

**Generated code before (Generated/TestClient.cs):**

```C#
namespace Azure.Service
{
    public partial class TestClient
    {
        public virtual ClientResult HelloAgain(BinaryContent p1, RequestOptions options = null)
        {
            Argument.AssertNotNull(p1, nameof(p1));
            using PipelineMessage message = CreateRequest(p1, options);
            return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
        }
    }
}
```

**Add customized client (TestClient.cs):**

```C#
namespace Azure.Service
{
    public partial class TestClient
    {
        // Renames `p1` to `content` and changes accessibility from public to internal.
        internal partial ClientResult HelloAgain(BinaryContent content, RequestOptions options);
    }
}
```

**Generated code after (Generated/TestClient.cs):**

```diff
namespace Azure.Service
{
    public partial class TestClient
    {
-        public virtual ClientResult HelloAgain(BinaryContent p1, RequestOptions options = null)
+        internal partial ClientResult HelloAgain(BinaryContent content, RequestOptions options)
        {
-            Argument.AssertNotNull(p1, nameof(p1));
-            using PipelineMessage message = CreateRequest(p1, options);
+            Argument.AssertNotNull(content, nameof(content));
+            using PipelineMessage message = CreateRequest(content, options);
            return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
        }
    }
}
```

</details>

## Replace any generated member

Works for model and client properties, methods, constructors etc.

Define a partial class with member with the same name and for methods same parameters.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public Model()
        {
            Property = "a";
        }

        public string Property { get; set; }
    }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        internal Model()
        {
            Property = "b";
        }
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
namespace Azure.Service.Models
{
    public partial class Model
    {
-        public Model()
-        {
-            Property = "a";
-        }
    }
}
```

</details>

## Remove any generated member

Works for model and client properties, methods, constructors etc.

Define a partial class with `[CodeGenSuppress("NameOfMember", typeof(Parameter1Type), typeof(Parameter2Type))]` attribute.

<details>

**Generated code before (Generated/Models/Model.cs):**

```C#
namespace Azure.Service.Models
{
    public partial class Model
    {
        public Model()
        {
            Property = "a";
        }

        public Model(string property)
        {
            Property = property;
        }

        public string Property { get; set; }
    }
}
```

**Add customized model (Model.cs)**

```C#
namespace Azure.Service.Models
{
    [CodeGenSuppress("Model", typeof(string))]
    public partial class Model
    {
    }
}
```

**Generated code after (Generated/Models/Model.cs):**

```diff
namespace Azure.Service.Models
{
    public partial class Model
    {
-        public Model(string property)
-        {
-            Property = property;
-        }
    }
}
```

</details>

## Extending a model with additional constructors

<details>

As with most customization, you can define a partial class for Models and extend them with methods and constructors.

**Generated code before (Generated/Models/Model.cs):**

```csharp
namespace Azure.Service.Models
{
    public partial class Model { }
}
```

**Add customized model (Model.cs)**

```csharp
namespace Azure.Service.Models
{
    public partial class Model {
        public Model(int x)
        {
        }
    }
}
```

</details>

---

### Packages Http Client Csharp .Tspd Docs Usage (`packages/http-client-csharp/.tspd/docs/usage.md`)

### Prerequisite

- Install [Node.js](https://nodejs.org/download/) 20 or above. (Verify by running `node --version`)
- Install [**.NET 8.0 SDK**](https://dotnet.microsoft.com/download/dotnet/8.0) for your specific platform. (or a higher version)

### Customizing Generated Code

For detailed instructions on how to customize the generated C# code, see the [Customization Guide](https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/.tspd/docs/customization.md).

### Experimental types and members

Use `@TypeSpec.HttpClient.experimental` to assign a public diagnostic ID to a generated
type or member and identify experiments used by its implementation:

```typespec
import "@typespec/http-client";

@TypeSpec.HttpClient.experimental(#{
  emitterScope: "@typespec/http-client-csharp",
  diagnosticId: "C",
  dependsOn: #["A", "B"],
})
op bar(): void;
```

The C# emitter adds `[Experimental("C")]` to the corresponding generated declaration:

| TypeSpec target                                       | Generated C# target                                           |
| ----------------------------------------------------- | ------------------------------------------------------------- |
| Model                                                 | Model class or struct                                         |
| Model property                                        | Property                                                      |
| Enum or union emitted as an enum                      | Enum or extensible-enum struct                                |
| Enum member or union variant emitted as an enum value | Enum field or extensible-enum property                        |
| Operation                                             | Synchronous and asynchronous protocol and convenience methods |
| Namespace or interface emitted as a client            | Client class                                                  |

For example, models and their properties can be separate experiments:

```typespec
@TypeSpec.HttpClient.experimental(#{ diagnosticId: "MODEL001" })
model Preview {
  @TypeSpec.HttpClient.experimental(#{ diagnosticId: "PROPERTY001" })
  value?: string;
}
```

Model factory methods expose the model's diagnostic. Partial serialization declarations
do not repeat the model attribute. Generated code suppresses diagnostics when referring
to source-annotated experimental types and members, so serialization, factories, and client
implementations can compile without changing the experimental status of other public APIs.

Suppressions surround only the member declarations or serialization blocks that need them,
including parameter and return types, generic arguments, and implementation references.
Explicit type-level `dependsOn` entries and base-type dependencies can require a type-wide
scope. References within a declaration carrying the same experimental diagnostic ID,
including its other partial declarations, do not need an additional suppression.
These suppressions do not affect diagnostics in consumer code or separate custom files.

Dependencies identify diagnostics rather than individual types: one diagnostic can apply
to multiple types or members, including those defined in external libraries. For externally
mapped types, source `@experimental` metadata is retained for generated-reference suppressions;
the emitter does not generate the external declaration or add attributes to its library.
This also covers client parameters exposed through generated settings and options properties.
Other external experiments require explicit `dependsOn` entries. They are not discovered by reflection.

Both metadata fields are optional. Without `diagnosticId`, no public experimental attribute
is added. Without `dependsOn`, no additional dependency diagnostics are requested; generated
references to source-annotated experiments are still handled. Emitter scopes apply to both fields.

Diagnostic IDs must be single C# warning identifiers (ASCII letters, digits, and underscores,
not starting with a digit) or decimal warning numbers. Whitespace, punctuation, comments, and
line breaks are rejected with `invalid-experimental-diagnostic-id` before generating C#.
An `ExperimentalAttribute` on a customized partial client or method takes precedence over
the generated attribute, including a polyfilled `System.Diagnostics.CodeAnalysis.ExperimentalAttribute`
on older target frameworks. Generated parent-client accessors suppress a child client's custom
diagnostic without marking the parent or accessor as experimental.

Some TypeSpec declarations have no corresponding C# declaration, such as scalars or unions
erased to built-in C# types without an explicit external mapping. C# also does not allow `ExperimentalAttribute` on parameters.
The emitter reports `experimental-target-not-supported` for these annotations instead of
silently dropping them or assigning their diagnostic to an unrelated API.

Models referenced by a union retain their own experimental metadata. Annotate the model
declaration, not the union variant that references it: a model variant has no separate C#
declaration on which to place an attribute.

Graduation is an explicit source change: dependencies becoming generally available, or
removing entries from `dependsOn`, does not remove `[Experimental("C")]`. Remove the
declaration's `@experimental` decorator when the public API is ready to graduate.

---

### Packages Http Client Csharp Generator Docs Architecture (`packages/http-client-csharp/generator/docs/architecture.md`)

# Generator Architecture

## Table of Contents

- [Architecture Overview](#architecture-overview)
- [Core Components](#core-components)
- [Generator Pipeline](#generator-pipeline)
- [Extensibility Framework](#extensibility-framework)
- [Testing Strategy](#testing-strategy)

## Architecture Overview

The TypeSpec Generator follows a layered architecture designed for extensibility and maintainability:

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Core Components

### 1. **Emitter Processing Layer**

- **`TypeSpec Emitter`**: TypeScript-based emitter that interfaces with the TypeSpec compiler
  - Parses TypeSpec API definitions and emitter options
  - Generates `configuration.json` with generator settings and emitter options
  - Creates `tspCodeModel.json` containing the serialized TypeSpec model
  - Invokes the `Microsoft.TypeSpec.Generator.dll` with translated command-line arguments
  - Serves as the bridge between TypeSpec tooling and the C# generator

### 2. **Input Processing Layer**

- **`Microsoft.TypeSpec.Generator.Input`**: Handles deserialization of TypeSpec JSON output
- **`InputLibrary`**: Entry point for loading and accessing TypeSpec model data
- **`InputTypes`**: Strongly-typed representations of TypeSpec constructs (models, operations, etc.)

### 3. **Code Model Generation Layer**

- **`CodeModelGenerator`**: Abstract base class defining the generator contract and extensibility points
- **`ScmCodeModelGenerator`**: Concrete implementation for System.ClientModel-based generators
- **`TypeFactory`**: Factory pattern for creating output type providers from input types
- **`GeneratorContext`**: Provides configuration and runtime context

### 4. **Output Model Layer**

- **`OutputLibrary`**: Container for all generated type providers
- **`TypeProvider`**: Abstract representation of generated types (models, enums, clients)
- **`Providers/`**: Concrete implementations for different code constructs:
  - `ModelProvider`: Data models with properties and serialization
  - `EnumProvider`: Enumeration types
  - `MethodProvider`: Client methods and operations
  - `PropertyProvider`: Model properties with accessors

### 5. **Transformation Pipeline**

- **`LibraryVisitor`**: Visitor pattern for traversing and modifying the output library
- **`LibraryRewriter`**: Advanced transformation capabilities for code modification
- **Plugin System**: MEF-based extensibility for custom transformations

### 6. **Code Generation Layer**

- **`Writers/`**: Responsible for converting providers to actual C# syntax
- **`Snippets/`**: Reusable code patterns and expressions
- **`Expressions/`**: Type-safe representation of C# expressions
- **`Statements/`**: Type-safe representation of C# statements

### 7. **Configuration & Context**

- **`Configuration`**: Centralized configuration management from JSON input
- **`GeneratorContext`**: Runtime context and dependency injection container
- **`SourceInputModel`**: Integration with existing custom code via Roslyn analysis

### 8. **Emitter Communication Layer**

- **`Emitter`**: JSON-RPC based communication channel for logging and diagnostics
  - Provides structured logging (info, debug, verbose) back to TypeSpec compiler
  - Reports diagnostics and errors with proper severity levels
  - Enables real-time feedback during code generation process
  - Facilitates integration with TypeSpec tooling and IDE extensions

## Generator Pipeline

The generation process follows a well-defined pipeline:

1. **Initialization**

   - Load configuration from `Configuration.json`
   - Initialize generator context and MEF composition
   - Load TypeSpec model from `tspCodeModel.json`

2. **Input Processing**

   - Deserialize TypeSpec JSON into strongly-typed input model
   - Validate and normalize input data
   - Build dependency graphs

3. **Code Model Generation**

   - Transform input types to output providers using TypeFactory
   - Apply generator-specific customizations
   - Build method signatures and type hierarchies


4. **Source Integration**

   - Analyze existing custom code using Roslyn
   - Merge custom implementations with generated code
   - Respect customization attributes and partial classes

5. **Visitor Pipeline**

   - Execute registered visitors in dependency order
   - Apply transformations, validations, and enhancements
   - Support for both built-in and plugin-provided visitors


6. **Code Generation**

   - Write providers to CodeFiles containing C# source code
   - Parse CodeFile content into syntax trees for Roslyn processing
   - Apply formatting and style conventions
   - Generate supporting files (model factories, serialization)

7. **Output**
   - Write generated files to target directories
   - Preserve custom code and configurations
   - Update project files and dependencies

## Extensibility Framework

The generator provides multiple extensibility points:

### **Generator Inheritance**

```csharp
[Export(typeof(CodeModelGenerator))]
public class CustomGenerator : CodeModelGenerator
{
    public override TypeFactory TypeFactory => new CustomTypeFactory();
    public override OutputLibrary OutputLibrary => new CustomOutputLibrary();
}
```

### **Custom Visitors**

```csharp
public class CustomLibraryVisitor : LibraryVisitor
{
    protected override TypeProvider? VisitModel(ModelProvider model)
    {
        // Custom model transformations
        return base.VisitModel(model);
    }
}
```

### **Plugin System**

```csharp
[Export(typeof(GeneratorPlugin))]
public class CustomPlugin : GeneratorPlugin
{
    public override void Apply(CodeModelGenerator generator)
    {
        generator.AddVisitor(new CustomVisitor());
    }
}
```

### **Type Factories**

```csharp
public class CustomTypeFactory : TypeFactory
{
    public override ModelProvider CreateModel(InputModelType inputModel)
    {
        // Custom model creation logic
        return new CustomModelProvider(inputModel);
    }
}
```

## Testing Strategy

The project employs a comprehensive testing approach:

### **Spector Tests**

- **Purpose**: Integration testing against HTTP specification test cases
- **Location**: `TestProjects/Spector/`
- **Approach**: Generates client libraries for HTTP-specs test cases and validates API surface
- **Stubbed Generation**: Minimizes repository size while maintaining API contract testing

### **Local Tests**

- **Purpose**: Unit and integration testing of generator components
- **Location**: `TestProjects/Local/`
- **Approach**: Direct testing of generator functionality with controlled inputs

### **Performance Tests**

- **Purpose**: Benchmarking generator performance and memory usage
- **Location**: Various `*.Tests.Perf` projects
- **Approach**: Measures generation time and resource consumption

### **Plugin Tests**

- **Purpose**: Validates extensibility framework and plugin system
- **Location**: `TestProjects/Plugin/`
- **Approach**: Tests custom generators and plugins

---

### Packages Http Client Csharp Generator Docs Backward Compatibility (`packages/http-client-csharp/generator/docs/backward-compatibility.md`)

# Backward Compatibility Support

## Table of Contents

- [Overview](#overview)
- [How It Works](#how-it-works)
- [Experimental Types](#experimental-types)
- [Supported Scenarios](#supported-scenarios)
  - [Model Factory Methods](#model-factory-methods)
    - [New Model Property Added](#scenario-new-model-property-added)
    - [Parameter Ordering Changed](#scenario-parameter-ordering-changed)
    - [Property Renamed](#scenario-property-renamed)
    - [New Property Added Together with a Rename](#scenario-new-property-added-together-with-a-rename)
  - [Model Properties](#model-properties)
  - [AdditionalProperties Type Preservation](#additionalproperties-type-preservation)
  - [Fixed Enum Members](#fixed-enum-members)
    - [Explicit (Non-contiguous) Values Preserved](#scenario-explicit-non-contiguous-values-preserved)
    - [Removed Integer Enum Member Re-added](#scenario-removed-integer-enum-member-re-added)
    - [Baseline-Accepted Removal Honored](#scenario-baseline-accepted-removal-honored)
  - [Extensible Enum Members](#extensible-enum-members)
    - [Removed Extensible Enum Member Re-added](#scenario-removed-extensible-enum-member-re-added)
  - [API Version Enum](#api-version-enum)
  - [Non-abstract Base Models](#non-abstract-base-models)
  - [Model Base Types](#model-base-types)
  - [Model Constructors](#model-constructors)
    - [Required Property Becomes Optional](#scenario-required-property-becomes-optional)
    - [Parameterless Constructor Becomes Parameterized](#scenario-parameterless-constructor-becomes-parameterized)
    - [Constructor Parameter Name Restored by Signature Match](#scenario-constructor-parameter-name-restored-by-signature-match)
  - [Parameter Naming](#parameter-naming)
    - [Page Size Parameter Casing Correction](#scenario-page-size-parameter-casing-correction)
    - [Top Parameter Conversion to MaxCount](#scenario-top-parameter-conversion-to-maxcount)
    - [Method Parameter Name Preserved from Last Contract](#scenario-method-parameter-name-preserved-from-last-contract)
  - [Content-Type Parameter Ordering](#content-type-parameter-ordering)
    - [Content-Type Before Body Preserved from Last Contract](#scenario-content-type-before-body-preserved-from-last-contract)
  - [Client Methods](#client-methods)
    - [Client Method Parameter Ordering Changed](#scenario-client-method-parameter-ordering-changed)
    - [New Optional Non-Body Parameter Added to a Service Method](#scenario-new-optional-non-body-parameter-added-to-a-service-method)
    - [Value-Type Parameter Nullability Removed](#scenario-value-type-parameter-nullability-removed)
    - [Nullable Optional Parameter Became Required](#scenario-nullable-optional-parameter-became-required)

## Overview

The TypeSpec C# generator supports backward compatibility (back-compat) to ensure that existing client code continues to work when the service API evolves. This is achieved by comparing the current generated code against a previous contract (assembly) and automatically generating compatibility shims where needed.

The backward compatibility system uses the `LastContractView` mechanism to access information about previously generated types, methods, and properties from the last released version of the library.

## How It Works

When generating code, the generator can optionally receive a compiled assembly from the previous version of the library (the "last contract"). The generator:

1. Analyzes the current TypeSpec specification and generates types based on the current API
2. Compares the generated types against the types in the last contract
3. Automatically generates compatibility methods, properties, or enum members where differences are detected

### Experimental Types

Types in the last released contract marked with `System.Diagnostics.CodeAnalysis.ExperimentalAttribute` are excluded from backward-compatibility lookup. The generator does not preserve their previous type shape or restore their previous members as compatibility shims, allowing those types to change when they graduate to stable or are removed.

This decision uses the attribute on the last released type, including polyfilled definitions of the attribute. Marking a previously stable type experimental in the current generation does not remove its compatibility guarantees. Experimental attributes on individual members in the last released contract also exclude those members from compatibility handling; attributes added only in the current generation do not remove guarantees for previously stable members.

### ApiCompat Baseline Awareness

Sometimes a breaking change (such as removing a model or a model factory method) is intentional and has already been reviewed and accepted. In the Azure SDK, such accepted breaking changes are recorded in an [ApiCompat](https://github.com/dotnet/sdk/tree/main/src/Compatibility) baseline (suppression) file, conventionally located at `eng/apicompatbaselines/<AssemblyName>.txt`.

Without awareness of these files, the back-compat system would resurrect every member present in the last contract — re-introducing the very API that was intentionally removed (and potentially referencing types that no longer exist). To prevent this, the generator discovers the baseline file by walking up from the project directory and parses its `TypesMustExist`, `MembersMustExist`, and `EnumValuesMustMatch` suppressions. The back-compat code then consults the baseline in the following ways:

- **Skipping resurrected members:** before regenerating a compatibility shim for a removed member, it checks whether the removal has been accepted in the baseline (matched by declaring-type full name, member name, and parameter count) and, if so, skips it.
- **Allowing property type changes:** the back-compat system normally preserves a property's previous (last-contract) type to avoid a breaking change. When that previous type — or a type nested within it (e.g. the element type of a collection) — has itself been intentionally removed and accepted in the baseline, preserving it would reference a now-deleted type. In that case the generator allows the property to take its current (spec) type instead.
- **Skipping re-added enum members:** before re-adding a fixed enum member that exists in the last contract but was dropped from the current spec, it checks whether that removal — or an accepted value difference recorded as `EnumValuesMustMatch` — has been accepted in the baseline (matched by the declaring enum's fully-qualified name and the member name) and, if so, omits the member.

> [!NOTE]
> Baseline awareness is currently wired into the base method back-compat path in `TypeProvider` (the parameter reorder/removal loop, inherited by `ClientProvider` and also used directly by `ModelFactoryProvider`), the model property type-preservation path (`ModelProvider`), and the fixed enum member path (`FixedEnumProvider`). The remaining back-compat consumers (`ModelProvider` constructors and `RestClientProvider`) can be made baseline-aware in the same way as a follow-up.

## Supported Scenarios

### Model Factory Methods

Model factory methods are public static methods that enable creating model instances for mocking and testing purposes. The generator attempts to maintain backward compatibility for these methods across API changes.

#### Scenario: New Model Property Added

**Description:** When a new property is added to a model, the generator creates a backward-compatible factory method overload that excludes the new parameter.

**Example:**

Previous version had a model with three properties:

```csharp
public static PublicModel1 PublicModel1(
    string stringProp = default,
    Thing modelProp = default,
    IEnumerable<string> listProp = default)
```

Current version adds a new property (`dictProp`):

```csharp
public static PublicModel1 PublicModel1(
    string stringProp = default,
    Thing modelProp = default,
    IEnumerable<string> listProp = default,
    IDictionary<string, string> dictProp = default)
```

**Generated Compatibility Method:**

```csharp
[EditorBrowsable(EditorBrowsableState.Never)]
public static PublicModel1 PublicModel1(
    string stringProp,
    Thing modelProp,
    IEnumerable<string> listProp)
{
    return PublicModel1(stringProp, modelProp, listProp, dictProp: default);
}
```

**Key Points:**

- The old method signature is preserved
- It delegates to the new method with default value for the new parameter
- Parameters in the compatibility method have no default values to avoid ambiguous call sites
- The method is marked with `[EditorBrowsable(EditorBrowsableState.Never)]` to hide it from IntelliSense

#### Scenario: Parameter Ordering Changed

**Description:** When only the parameter ordering changes in a factory method (same parameters, different order), the generator replaces the current method with the previous method signature.

**Example:**

Previous version:

```csharp
public static PublicModel1 PublicModel1(
    Thing modelProp = default,
    string stringProp = default,
    IEnumerable<string> listProp = default,
    IDictionary<string, string> dictProp = default)
```

Current version would generate different ordering:

```csharp
public static PublicModel1 PublicModel1(
    string stringProp = default,
    Thing modelProp = default,
    IEnumerable<string> listProp = default,
    IDictionary<string, string> dictProp = default)
```

**Result:** The generator keeps the previous parameter ordering to maintain compatibility.

#### Scenario: Property Renamed

**Description:** When a model property is renamed (via `@@clientName`, a spec rename, a generator naming-rule change, etc.), the generated factory parameter would normally change its name to follow the new property name. Renaming a parameter is source-breaking for callers using named arguments and is not flagged by ApiCompat / binary-compat tooling. To avoid this, the generator preserves the previous parameter name on the current factory method whenever the only difference between the previous and current method is one or more parameter names (same method name, same parameter types in the same order, same parameter count).

**Example:**

Previous version exposed `stringProp` and `modelProp`:

```csharp
public static PublicModel1 PublicModel1(
    string stringProp = default,
    Thing modelProp = default,
    IEnumerable<string> listProp = default,
    IDictionary<string, string> dictProp = default)
```

Current TypeSpec renames the underlying properties to `CertificateStringProp` and `CertificateModelProp`, which would normally produce:

```csharp
public static PublicModel1 PublicModel1(
    string certificateStringProp = default,
    Thing certificateModelProp = default,
    IEnumerable<string> listProp = default,
    IDictionary<string, string> dictProp = default)
```

**Generated Compatibility Result:**

The generator detects that previous and current methods differ only in parameter names and preserves the previous names on the current method:

```csharp
public static PublicModel1 PublicModel1(
    string stringProp = default,
    Thing modelProp = default,
    IEnumerable<string> listProp = default,
    IDictionary<string, string> dictProp = default)
{
    // body uses the preserved names when constructing the model
    return new PublicModel1(stringProp, modelProp, listProp.ToList(), dictProp, additionalBinaryDataProperties: null);
}
```

**Key Points:**

- Only one method is generated — no additional `[EditorBrowsable(EditorBrowsableState.Never)]` overload is needed
- Existing source code using named arguments (e.g. `PublicModel1(stringProp: "x")`) continues to compile
- The matching is by method name plus parameter types in the same order; the parameter count must also match. If a parameter is added or removed in addition to a rename, the standard "new property added" overload is generated instead (see scenario below)
- The XML doc `<param>` entries on the method are updated to reference the preserved names

#### Scenario: New Property Added Together with a Rename

**Description:** When a new property is added to a model AND a previously-published property has been renamed at the same time, the parameter counts of the previous and current factory methods differ, so the rename-only fast path above does not apply. The generator falls back to the standard "new property added" flow and emits an `[EditorBrowsable(EditorBrowsableState.Never)]` backcompat overload using the previously-published parameter names.

> [!NOTE]
> The body of the backcompat overload constructs the model directly. Renamed parameters whose names no longer match a current property are passed as `default` to the constructor, since the body can no longer thread them through the renamed properties. This keeps existing source compiling, but callers who depended on the old parameter being forwarded should migrate to the current method.

**Example:**

Previous version exposed three properties, with the first two under different names:

```csharp
public static PublicModel1 PublicModel1(
    string oldStringProp = default,
    Thing oldModelProp = default,
    IEnumerable<string> listProp = default)
```

Current TypeSpec renames the first two properties (now `stringProp` / `modelProp`) and adds a new property (`dictProp`):

```csharp
public static PublicModel1 PublicModel1(
    string stringProp = default,
    Thing modelProp = default,
    IEnumerable<string> listProp = default,
    IDictionary<string, string> dictProp = default)
```

**Generated Compatibility Method:**

```csharp
[EditorBrowsable(EditorBrowsableState.Never)]
public static PublicModel1 PublicModel1(
    string oldStringProp,
    Thing oldModelProp,
    IEnumerable<string> listProp)
{
    listProp ??= new ChangeTrackingList<string>();

    return new PublicModel1(default, default, listProp.ToList(), default, additionalBinaryDataProperties: null);
}
```

**Key Points:**

- The previous (renamed) signature is preserved so existing source code continues to compile
- Parameters whose names matched a current property (`listProp`) are threaded through; renamed parameters are passed as `default`
- The new property is also passed as `default`
- A separate visible method exposes the current signature with the new property and the renamed parameters

### Model Properties

The generator preserves the previous property type whenever it differs from the type produced by the current spec. This applies to all public model properties (scalars, enums, models, and collections), so any property type change is non-source-breaking by default. Users who want the new spec's type to take effect can override this behavior with custom code.

#### Scenario: Collection Property Type Changed

**Description:** When a property type changes from a read-only collection to a read-write collection (or vice versa), the generator preserves the previous property type to avoid breaking changes.

**Example:**

Previous version:

```csharp
public IReadOnlyList<string> Items { get; }
```

Current TypeSpec would generate:

```csharp
public IList<string> Items { get; set; }
```

**Result:** The generator detects the type mismatch and preserves the previous type:

```csharp
public IReadOnlyList<string> Items { get; }
```

#### Scenario: Scalar/Model Property Type Changed

**Description:** When the type of a scalar, enum, or model property differs between the last contract and the current spec, the generator preserves the last contract's type shape. Nullable value-type differences also preserve the last contract's nullability.

Reference types loaded from the last contract are nullable-oblivious, so their top-level nullability is not used as compatibility evidence. The generator retains the current TypeSpec top-level reference nullability while preserving any other last-contract type differences, including nested generic argument types. This prevents compatibility processing from adding null guards or null-unsafe collection conversions that contradict the current wire contract.

**Example:**

Previous version:

```csharp
public int? Count { get; set; }
```

Current TypeSpec would generate:

```csharp
public int Count { get; set; }
```

**Result:** The generator detects the type mismatch and preserves the previous nullable type:

```csharp
public int? Count { get; set; }
```

A diagnostic message is logged for every overridden property: `"Changed property {ModelName}.{PropertyName} type to {LastContractType} to match last contract."`

### AdditionalProperties Type Preservation

The generator maintains backward compatibility for the `AdditionalProperties` property type on models that extend or use `Record<unknown>`.

#### Scenario: AdditionalProperties Type Changed from Object to BinaryData

**Description:** When a model with additional properties was previously generated with `IDictionary<string, object>`, but the current generator would produce `IDictionary<string, BinaryData>`, the generator preserves the previous `object` type to maintain backward compatibility.

This commonly occurs when:

- Migrating from an older generator version that used `object` for unknown additional property values
- Regenerating a library that was originally created with `IDictionary<string, object>` for `Record<unknown>` types

**Example:**

Previous version generated with object type:

```csharp
public partial class MyModel
{
    private readonly IDictionary<string, object> _additionalBinaryDataProperties;

    public MyModel(string name, IDictionary<string, object> additionalProperties)
    {
        Name = name;
        _additionalBinaryDataProperties = additionalProperties;
    }

    public string Name { get; set; }
    public IDictionary<string, object> AdditionalProperties { get; }
}
```

Current TypeSpec would generate with BinaryData:

```csharp
public partial class MyModel
{
    private readonly IDictionary<string, BinaryData> _additionalBinaryDataProperties;

    public MyModel(string name, IDictionary<string, BinaryData> additionalProperties)
    {
        Name = name;
        _additionalBinaryDataProperties = additionalProperties;
    }

    public string Name { get; set; }
    public IDictionary<string, BinaryData> AdditionalProperties { get; }
}
```

**Generated Compatibility Result:**

When the last contract had `IDictionary<string, object>`, the generator preserves the object type:

```csharp
public partial class MyModel
{
    private readonly IDictionary<string, object> _additionalBinaryDataProperties;

    public MyModel(string name, IDictionary<string, object> additionalProperties)
    {
        Name = name;
        _additionalBinaryDataProperties = additionalProperties;
    }

    public string Name { get; set; }
    public IDictionary<string, object> AdditionalProperties { get; }
}
```

**Key Points:**

- Applies to models with `AdditionalProperties` defined via `Record<unknown>` or similar patterns
- The backing field type is changed from `IDictionary<string, BinaryData>` to `IDictionary<string, object>`
- The property type matches the backing field type to avoid compilation errors
- Serialization and deserialization automatically handle both `object` and `BinaryData` types
- For object types, deserialization uses `JsonElement.GetObject()` instead of wrapping in `BinaryData`
- For object types, serialization uses `Utf8JsonWriter.WriteObjectValue<object>()` to handle arbitrary values
- Binary compatibility is fully maintained - existing client code continues to work without recompilation

### Fixed Enum Members

Fixed enums (C# `enum` types) preserve their previously shipped members and values by comparing the current spec against the last contract. Because the underlying value of an integer-backed enum member is part of its public API, the generator keeps those values stable across regenerations, aligns member order to the last contract, and re-adds members that were dropped from the current spec.

> [!NOTE]
> These behaviors apply to **integer-backed** fixed enums (`int`/`long`).

#### Scenario: Explicit (Non-contiguous) Values Preserved

**Description:** When an integer enum's members carry explicit, non-contiguous values, the generator preserves each member's exact value from the last contract instead of reassigning positional ordinals.

**Example:**

Previous version (GA surface):

```csharp
public enum CapacityReservationLevel
{
    OneHundred = 100,
    TwoHundred = 200,
    FiveHundred = 500,
}
```

**Generated Result:** The members keep their exact values (`100`, `200`, `500`) rather than being reassigned to `0`, `1`, `2`.

#### Scenario: Removed Integer Enum Member Re-added

**Description:** When an integer enum member present in the last contract is dropped from the current spec, the generator re-adds it — at its original position and with its original explicit value — to avoid removing a previously shipped member.

**Example:**

Previous version:

```csharp
public enum SampleEnum
{
    Alpha = 0,
    Beta = 1,
    Gamma = 2,
}
```

Current TypeSpec removes `Beta`:

```csharp
public enum SampleEnum
{
    Alpha = 0,
    Gamma = 2,
}
```

**Generated Result:** `Beta` is re-added at its original position with its original value:

```csharp
public enum SampleEnum
{
    Alpha = 0,
    Beta = 1,
    Gamma = 2,
}
```

**Key Points:**

- Members shared between the current spec and the last contract are ordered to match the last contract and keep their last-contract values
- New members introduced by the current spec are appended after the last-contract members, keeping their spec values
- The re-added member's underlying value is read from the previously published assembly's metadata (no debug symbols required)

#### Scenario: Baseline-Accepted Removal Honored

**Description:** When the removal of an enum member has been intentionally accepted in the [ApiCompat baseline](#apicompat-baseline-awareness) — recorded as a `MembersMustExist` removal or an `EnumValuesMustMatch` value-difference suppression — the generator honors that decision and does **not** re-add the member.

**Key Points:**

- Suppressed members are matched by the declaring enum's fully-qualified name and the member name
- This lets a library intentionally drop a previously shipped enum member once the removal is reviewed and recorded in the baseline

### Extensible Enum Members

Extensible enums (C# `readonly partial struct` types) preserve their previously shipped members by comparing the current spec against the last contract. The generator re-adds an extensible enum member that was dropped from the current spec, restoring it with its original wire value to avoid removing a previously shipped member.

#### Scenario: Removed Extensible Enum Member Re-added

**Description:** When an extensible enum member present in the last contract is dropped from the current spec, the generator restores it — as a public static property backed by its recovered `const` wire value — to keep the previously shipped API.

**Example:**

Previous version:

```csharp
public readonly partial struct OperationStatusType : IEquatable<OperationStatusType>
{
    private const string CompletedValue = "Completed";
    private const string FailedValue = "Failed";
    private const string RunningValue = "Running";

    public static OperationStatusType Completed { get; } = new OperationStatusType(CompletedValue);
    public static OperationStatusType Failed { get; } = new OperationStatusType(FailedValue);
    public static OperationStatusType Running { get; } = new OperationStatusType(RunningValue);
    // ...
}
```

Current TypeSpec removes `Running`. **Generated Result:** `Running` is re-added (appended after the current members) with its original wire value:

```csharp
public readonly partial struct OperationStatusType : IEquatable<OperationStatusType>
{
    private const string CompletedValue = "Completed";
    private const string FailedValue = "Failed";
    private const string RunningValue = "Running";

    public static OperationStatusType Completed { get; } = new OperationStatusType(CompletedValue);
    public static OperationStatusType Failed { get; } = new OperationStatusType(FailedValue);
    public static OperationStatusType Running { get; } = new OperationStatusType(RunningValue);
    // ...
}
```

**Key Points:**

- Members that already exist in the current spec, are provided by custom code, or whose removal is accepted in the [ApiCompat baseline](#apicompat-baseline-awareness) are not re-added
- Restored members are appended after the current spec's members, preserving the current spec's order

### API Version Enum

Service version enums maintain backward compatibility by preserving version values from previous releases.

#### Scenario: API Version Removed or Changed

**Description:** When API versions are removed or changed in the TypeSpec, the generator preserves previous version enum members to prevent breaking existing code that references them.

**Example:**

Previous version had enum members:

```csharp
public enum ServiceVersion
{
    V2021_10_01 = 1,
    V2022_01_01 = 2,
    V2022_06_01 = 3,
}
```

Current TypeSpec removes `V2021_10_01` and adds `V2023_01_01`:

```csharp
public enum ServiceVersion
{
    V2022_01_01 = 1,
    V2022_06_01 = 2,
    V2023_01_01 = 3,
}
```

**Generated Result:**

```csharp
public enum ServiceVersion
{
    V2021_10_01 = 1,  // Preserved from previous version
    V2022_01_01 = 2,
    V2022_06_01 = 3,
    V2023_01_01 = 4,
}
```

**Key Points:**

- Previous enum members are preserved even if removed from TypeSpec
- Enum values are re-indexed to maintain sequential ordering
- Version format and separator are detected from current versions and applied to previous versions

### Non-abstract Base Models

#### Scenario: The previous version of a base model was defined as non-abstract.

**Description:** This can occur if the library was generated using a different generator that supported non-abstract base models. In such cases, the generator preserves the non-abstract nature of the base model to maintain compatibility.

**Example:**

Previous version generated using a different generator:

```csharp
public class BaseModel
{
    public string CommonProperty { get; set; }
}
```

Current TypeSpec would generate:

```csharp
public class BaseModel
{
    public string CommonProperty { get; set; }
}
```

### Model Constructors

The generator maintains backward compatibility for model constructors on abstract base types to prevent breaking changes when constructor accessibility changes.

#### Scenario: Public Constructor on Abstract Base Type

**Description:** When an abstract base type had a public constructor in the previous version, but the current TypeSpec generation would create a `private protected` constructor, the generator automatically changes the modifier to `public` to maintain backward compatibility.

This commonly occurs when:

- Migrating from autorest-generated code to TypeSpec-generated code
- Abstract base types with discriminators had public parameterless constructors in previous versions

**Example:**

Previous version had a public parameterless constructor:

```csharp
public abstract partial class SearchIndexerDataIdentity
{
    /// <summary> Initializes a new instance of SearchIndexerDataIdentity. </summary>
    public SearchIndexerDataIdentity()
    {
    }
}
```

Current TypeSpec would generate a private protected constructor:

```csharp
public abstract partial class SearchIndexerDataIdentity
{
    /// <summary> Initializes a new instance of SearchIndexerDataIdentity. </summary>
    /// <param name="odataType"> A URI fragment specifying the type of identity. </param>
    private protected SearchIndexerDataIdentity(string odataType)
    {
        OdataType = odataType;
    }
}
```

**Generated Compatibility Result:**

When a matching public constructor exists in the last contract, the modifier is changed from `private protected` to `public`:

```csharp
public abstract partial class SearchIndexerDataIdentity
{
    /// <summary> Initializes a new instance of SearchIndexerDataIdentity. </summary>
    /// <param name="odataType"> A URI fragment specifying the type of identity. </param>
    public SearchIndexerDataIdentity(string odataType)
    {
        OdataType = odataType;
    }
}
```

**Key Points:**

- Only applies to abstract base types
- The constructor must have matching parameters (same count, types, and names)
- The modifier is changed from `private protected` to `public`
- No additional constructors are generated; only the accessibility is adjusted

#### Scenario: Required Property Becomes Optional

**Description:** When a required model property becomes optional, the current initialization constructor no longer includes that property. To preserve source compatibility for callers that construct the model positionally, the generator restores the previously published public constructor as an overload. The restored overload chains to the closest current public constructor and assigns the now-optional property.

**Example:**

Previous version required both properties:

```csharp
public partial class Widget
{
    public Widget(string name, string description)
    {
        Name = name;
        Description = description;
    }

    public string Name { get; }
    public string Description { get; }
}
```

Current TypeSpec makes `description` optional:

```csharp
public partial class Widget
{
    public Widget(string name)
    {
        Name = name;
    }

    public string Name { get; }
    public string Description { get; set; }
}
```

**Generated Compatibility Result:**

```csharp
public Widget(string name, string description) : this(name)
{
    Description = description;
}
```

**Key Points:**

- The previous constructor must be public and no generated or custom constructor may already have the same parameters.
- Every parameter removed from the current constructor must map to a public, settable property with the same type. Properties renamed through a code-generation customization are supported.
- The current constructor used for chaining must have parameters that match an in-order subset of the previous constructor's parameters.
- When no current public constructor is such an in-order subset, there is no safe chain target, so the previous constructor is not restored. A standalone constructor is not generated because it would bypass the current constructor's initialization (for example, the implicit `base()` call and inherited get-only properties).
- If the constructor removal is accepted in an ApiCompat baseline, the generator does not restore it.

#### Scenario: Parameterless Constructor Becomes Parameterized

**Description:** When a model previously exposed an accessible parameterless constructor and a property later becomes required, generation replaces the parameterless constructor with one that accepts the required property. The generator restores the previous parameterless constructor and chains it to an appropriate current constructor with `default` values.

**Example:**

Previous version exposed a parameterless constructor:

```csharp
public partial class Widget
{
    protected Widget()
    {
    }

    public string Name { get; set; }
}
```

Current TypeSpec makes `name` required:

```csharp
public partial class Widget
{
    protected Widget(string name)
    {
        Name = name;
    }

    public string Name { get; }
}
```

**Generated Compatibility Result:**

```csharp
protected Widget() : this(default)
{
}
```

**Key Points:**

- The previous parameterless constructor must be accessible and no accessible generated or custom parameterless constructor may already exist.
- The restored constructor retains the previous accessibility.
- The generator prefers an accessible current constructor with the fewest required parameters as the chain target. When necessary, it can chain to a `private protected` initialization constructor.
- The generated parameterless mocking constructor is removed so it does not duplicate the restored constructor.
- If the constructor removal is accepted in an ApiCompat baseline, the generator does not restore it.

#### Scenario: Constructor Parameter Name Restored by Signature Match

**Description:** When a constructor keeps the same parameter types (in the same order and count) but one or more parameters would be renamed — because of a `@@clientName`, a spec/property rename, a generator naming-rule change, or a casing correction — the new names would appear on the generated constructor. Renaming a constructor parameter is source-breaking for callers using named arguments and is reported by ApiCompat as a `CP0017` parameter-name change, even though ordinary binary-compatibility checks may miss it. To avoid this, the generator matches the current constructor to the previously published one by signature and restores the previous parameter names.

This covers straight renames, casing corrections, and parameter **swaps/rotations**. For a swap or rotation (every previous name is still present, just in a different position) the generator realigns the existing parameter objects to the previous positional order instead of renaming positionally, so a caller's named argument stays bound to the same property.

**Example:**

Previous version published `(name, vmSkuName)`:

```csharp
public MockInputModel(string name, string vmSkuName)
{
    Name = name;
    VmSkuName = vmSkuName;
}
```

Current TypeSpec orders the properties differently, which would normally produce `(vmSkuName, name)`. The generator restores the previous parameter order and names:

```csharp
public MockInputModel(string name, string vmSkuName)
{
    VmSkuName = vmSkuName;
    Name = name;
}
```

### Parameter Naming

The generator maintains backward compatibility for parameter names to ensure that existing code continues to compile when parameter names are corrected, standardized, or converted to follow naming conventions.

#### Scenario: Page Size Parameter Casing Correction

**Description:** When a paging parameter name has incorrect casing in the TypeSpec (e.g., `maxpagesize` instead of `maxPageSize`), the generator handles it in two ways:

1. **If the parameter exists in LastContractView**: The generator uses the exact casing from the previous version to maintain backward compatibility
2. **If the parameter does NOT exist in LastContractView**: The generator normalizes common badly-cased variants to proper camelCase (e.g., `maxpagesize` → `maxPageSize`)

This commonly occurs when:

- TypeSpec defines a paging parameter with non-standard casing (e.g., all lowercase)
- The generator needs to maintain API consistency while respecting the wire format
- New paging operations need standardized parameter naming

**Example:**

**Case 1: Parameter exists in LastContractView - badly-cased is preserved (backward compatibility)**

Previous version had badly-cased parameter name:

```csharp
public virtual AsyncPageable<Item> GetItemsAsync(int? maxpagesize = null, CancellationToken cancellationToken = default)
{
    HttpMessage CreateRequest()
    {
        var message = pipeline.CreateMessage();
        var request = message.Request;
        request.Method = RequestMethod.Get;
        var uri = new RequestUriBuilder();
        uri.Reset(endpoint);
        uri.AppendPath("/items", false);
        if (maxpagesize != null)
        {
            uri.AppendQuery("maxpagesize", maxpagesize.Value, true);  // Serialized name from spec
        }
        // ...
    }
    // ...
}
```

Current TypeSpec still defines parameter with bad casing:

```typespec
@query maxpagesize?: int32;  // Lowercase in spec
```

**Generated Compatibility Result:**

The generator detects the parameter in LastContractView and preserves its exact badly-cased name to maintain backward compatibility:

```csharp
public virtual AsyncPageable<Item> GetItemsAsync(int? maxpagesize = null, CancellationToken cancellationToken = default)
{
    HttpMessage CreateRequest()
    {
        var message = pipeline.CreateMessage();
        var request = message.Request;
        request.Method = RequestMethod.Get;
        var uri = new RequestUriBuilder();
        uri.Reset(endpoint);
        uri.AppendPath("/items", false);
        if (maxpagesize != null)
        {
            uri.AppendQuery("maxpagesize", maxpagesize.Value, true);  // Still badly-cased for backward compatibility
        }
        // ...
    }
    // ...
}
```

**Case 2: Parameter does NOT exist in LastContractView - badly-cased is normalized**

New paging operation with badly-cased parameter (no previous version):

```typespec
@query maxpagesize?: int32;  // Lowercase in spec
```

**Generated Result:**

The generator normalizes the parameter name to proper camelCase since there's no previous version to maintain compatibility with:

```csharp
public virtual AsyncPageable<Item> GetItemsAsync(int? maxPageSize = null, CancellationToken cancellationToken = default)
{
    HttpMessage CreateRequest()
    {
        var message = pipeline.CreateMessage();
        var request = message.Request;
        request.Method = RequestMethod.Get;
        var uri = new RequestUriBuilder();
        uri.Reset(endpoint);
        uri.AppendPath("/items", false);
        if (maxPageSize != null)
        {
            uri.AppendQuery("maxpagesize", maxPageSize.Value, true);  // Serialized name still uses spec's casing
        }
        // ...
    }
    // ...
}
```

**Key Points:**

- **Case 1 (Backward compatibility)**: If the parameter exists in LastContractView, its exact casing is preserved - even if badly-cased
- **Case 2 (Normalization)**: If the parameter does NOT exist in LastContractView, badly-cased variants are normalized to proper camelCase
- The HTTP query parameter always uses the original serialized name from the spec (e.g., `maxpagesize`)
- Existing client code continues to compile without changes

#### Scenario: Top Parameter Conversion to MaxCount

**Description:** For paging operations, the generator converts the `top` parameter to `maxCount` to follow standard naming conventions. However, backward compatibility is maintained in two ways:

1. **If the `top` parameter exists in LastContractView**: The generator preserves the `top` parameter name (with its exact casing) to maintain backward compatibility
2. **If the `top` parameter does NOT exist in LastContractView**: The generator converts `top` to the standardized `maxCount` parameter name

This commonly occurs when:

- Migrating from an older API version or generator that used `top` for pagination limits
- TypeSpec defines paging operations with a `top` parameter
- The generator needs to standardize on `maxCount` while maintaining backward compatibility

**Example:**

**Case 1: Top parameter exists in LastContractView - preserved for backward compatibility**

Previous version had `top` parameter:

```csharp
public virtual AsyncPageable<Item> GetItemsAsync(int? top = null, CancellationToken cancellationToken = default)
{
    HttpMessage CreateRequest()
    {
        var message = pipeline.CreateMessage();
        var request = message.Request;
        request.Method = RequestMethod.Get;
        var uri = new RequestUriBuilder();
        uri.Reset(endpoint);
        uri.AppendPath("/items", false);
        if (top != null)
        {
            uri.AppendQuery("top", top.Value, true);  // Serialized name from spec
        }
        // ...
    }
    // ...
}
```

Current TypeSpec still defines `top` parameter:

```typespec
op getItems(@query top?: int32): Page<Item>;
```

**Generated Compatibility Result:**

The generator detects the `top` parameter in LastContractView and preserves it exactly to maintain backward compatibility:

```csharp
public virtual AsyncPageable<Item> GetItemsAsync(int? top = null, CancellationToken cancellationToken = default)
{
    HttpMessage CreateRequest()
    {
        var message = pipeline.CreateMessage();
        var request = message.Request;
        request.Method = RequestMethod.Get;
        var uri = new RequestUriBuilder();
        uri.Reset(endpoint);
        uri.AppendPath("/items", false);
        if (top != null)
        {
            uri.AppendQuery("top", top.Value, true);  // Still uses "top" for backward compatibility
        }
        // ...
    }
    // ...
}
```

**Case 2: Top parameter does NOT exist in LastContractView - converted to maxCount**

New paging operation with `top` parameter (no previous version):

```typespec
op getItems(@query top?: int32): Page<Item>;
```

**Generated Result:**

The generator converts the parameter name to standardized `maxCount` since there's no previous version to maintain compatibility with:

```csharp
public virtual AsyncPageable<Item> GetItemsAsync(int? maxCount = null, CancellationToken cancellationToken = default)
{
    HttpMessage CreateRequest()
    {
        var message = pipeline.CreateMessage();
        var request = message.Request;
        request.Method = RequestMethod.Get;
        var uri = new RequestUriBuilder();
        uri.Reset(endpoint);
        uri.AppendPath("/items", false);
        if (maxCount != null)
        {
            uri.AppendQuery("top", maxCount.Value, true);  // Serialized name still uses "top" from spec
        }
        // ...
    }
    // ...
}
```

**Key Points:**

- **Case 1 (Backward compatibility)**: If `top` parameter exists in LastContractView, its exact name and casing are preserved
- **Case 2 (Standardization)**: If `top` parameter does NOT exist in LastContractView, it is converted to `maxCount` for consistency
- The HTTP query parameter always uses the original serialized name from the spec (e.g., `top`)
- This conversion is specific to paging operations only
- Existing client code with `top` continues to compile without changes
- New code benefits from the standardized `maxCount` naming convention

#### Scenario: Method Parameter Name Preserved from Last Contract

**Description:** When a service method parameter is renamed by the spec or by the generator (e.g., a `@@clientName`, a TypeSpec property rename, or a generator naming-rule change), the new name would normally appear on the generated convenience and protocol methods. Renaming a parameter is source-breaking for callers using named arguments and is not flagged by ApiCompat / binary-compat tooling. To avoid this, the generator looks up the parameter's original (spec) name in `LastContractView` and, when a previously-published parameter with that name exists on the matching method (matched by method name, allowing for the sync/async pair), restores the previously-published parameter name on the current method.

This generalizes the paging-specific `top → maxCount` and page-size casing scenarios above so that any renamed parameter on any operation falls back to the prior published name.

**Example:**

Previous version exposed `oldParam` on `GetSomething`:

```csharp
public virtual ClientResult GetSomething(string oldParam, RequestOptions options = null)
{
    // ...
}
```

Current TypeSpec renames the parameter to `newParam` (e.g., via `@@clientName` or a property rename), which would normally produce:

```csharp
public virtual ClientResult GetSomething(string newParam, RequestOptions options = null)
{
    // ...
}
```

**Generated Compatibility Result:**

The generator detects `oldParam` on the matching method in `LastContractView` and restores that name on the current method:

```csharp
public virtual ClientResult GetSomething(string oldParam, RequestOptions options = null)
{
    // body and HTTP request still use the spec's serialized name; only the public parameter name is preserved
}
```

**Key Points:**

- Lookup is scoped to the matching service method (allowing for the sync/async pair) so a parameter name shared across multiple methods cannot false-match another method's parameter
- The HTTP query/path/header/body serialized name continues to use the spec's wire name — only the C# parameter identifier is restored
- Existing source code using named arguments (e.g., `client.GetSomething(oldParam: "x")`) continues to compile
- If no matching parameter is found in `LastContractView`, the generator uses the current (renamed) name

### Content-Type Parameter Ordering

The generator places the `contentType` parameter after the body (`content`) parameter in method signatures. However, backward compatibility is maintained when the last contract had a different ordering.

#### Scenario: Content-Type Before Body Preserved from Last Contract

**Description:** The generator places `contentType` after the `content` (body) parameter. However, if the last contract had `contentType` before `content`, the generator preserves that ordering to avoid breaking existing code.

This commonly occurs when a library was previously generated with contentType before body and has already been released (GA'd).

**Example:**

**contentType before body exists in LastContractView - preserved for backward compatibility**

Previous version had `contentType` before `content`:

```csharp
public virtual ClientResult UpdateSkillDefaultVersion(string skillId, string contentType, BinaryContent content, RequestOptions options = null)
{
    // ...
}
```

Current TypeSpec defines a content type:

```typespec
op UpdateSkillDefaultVersion(
  @path skill_id: string,
  @header contentType: string,
  @body body: SetDefaultSkillVersionBody,
): SkillResource;
```

**Generated Compatibility Result:**

The generator detects that the previous contract had `contentType` before `content` and preserves that ordering:

```csharp
public virtual ClientResult UpdateSkillDefaultVersion(string skillId, string contentType, BinaryContent content, RequestOptions options = null)
{
    // contentType stays before content for backward compatibility
}
```

### Model Base Types

The generator can preserve a previously shipped model base when the current TypeSpec hierarchy no longer contains it. Automatic restoration is intentionally limited to compatible generated root models and mapped `SystemObjectModelProvider` bases. For ordinary generated bases, both the derived model and displaced current base must be memberless. Mapped restoration requires a current input base, which remains the authoritative wire contract while the shipped CLR property and constructor surface is restored.

When no current provider represents the shipped CLR base, a downstream generator can override `TypeFactory.CreateLastContractModelBaseCore` to supply a mapping for its known inheritable framework types. The returned type is still subject to the standard mapped-base compatibility checks and remains local to the model being restored. A mapped base is not reconstructed when the current model has become a root because there is no separate current-base contract to reconcile safely.

The current base is retained when broader reconciliation would be required, including a conflicting custom base declaration, structs, polymorphic or derived hierarchies, arbitrary referenced types, and constructed generic bases. Unrelated custom members are permitted only for mapped-base restoration; generated-base restoration with custom code remains unsupported.

A derived generator can override `ModelProvider.RequiresParameterlessBaseConstructor` to require a mapped constructor callable without arguments before the restored hierarchy is committed. ClientModel enables this requirement for JSON/XML and multipart-form-data models, because their serialization partials can emit an empty constructor with an implicit `base()` call. The constructor must be public or protected and pass the existing overload and attribute checks. This check does not apply to core providers or ClientModel models without JSON/XML or multipart-form-data serialization; it does not synthesize constructor arguments.

Restoration checks the shipped property/accessor and method contracts, including nullable value types, parameter names, ref modifiers, `params`, optional defaults, and interface assignability. The default mapped input/property check requires matching value-type nullability; intentional downstream shape changes remain explicit compatibility-hook overrides. A selected historical constructor must also match its bound properties' value-type nullability. When a current property visitor removes a property, symbol-backed restoration does not reintroduce its historical declaration and the one-to-one checks reject restoration. Both full and initialization constructor calls must be provably callable on the mapped target; ambiguous overloads and changed omitted defaults are rejected. Generated-base constructors must remain property-backed. Historical generic methods, constants, by-ref returns, indexers, required-member properties, and defaults that cannot be represented losslessly are rejected rather than reconciled. Public or protected historical nested type declarations are also rejected for generated-base and symbol-backed mapped-base restoration; nested type emission and CLR nested-type reconciliation are not supported. These checks do not rediscover the complete CLR surface of an ordinary downstream mapping whose input omits members.

### Client Methods

#### Scenario: Client Method Parameter Ordering Changed

**Description:** When only the parameter ordering changes in a client method, the generator restores the order from `LastContractView` on the current method instead of adding a compatibility overload. This preserves existing positional calls to both protocol and convenience methods, including their synchronous and asynchronous variants. A previous contract must be available; without it, the generator uses the current parameter order.

**Example:**

Previous version of the client:

```csharp
public virtual ClientResult GetData(BinaryContent content, int count, bool includeDetails, RequestOptions options = null);
public virtual ClientResult<string> GetData(string data, int count, bool includeDetails, CancellationToken cancellationToken = default);
```

Current TypeSpec moves `includeDetails` before `count`, which would normally change the order of those parameters in the generated methods:

```typespec
op getData(@body data: string, @header includeDetails: boolean, @query count: int32): string;
```

**Generated Compatibility Result:**

The generator keeps the previously published order on both methods:

```csharp
public virtual ClientResult GetData(BinaryContent content, int count, bool includeDetails, RequestOptions options = null);
public virtual ClientResult<string> GetData(string data, int count, bool includeDetails, CancellationToken cancellationToken = default);
```

The corresponding `GetDataAsync` methods likewise preserve their own last-contract parameter order.

**Key Points:**

- The method name and return type must match the previous contract, with the same parameter count and parameters matched by normalized name and type. Adding or removing parameters or changing their types is not part of this scenario.
- Protocol and convenience methods are matched independently, so their parameter orders can be restored separately or together.
- When a protocol method is reordered, convenience method calls to it are updated to pass arguments in the restored order.
- Parameter XML documentation is reordered to match the restored signature.

#### Scenario: New Optional Non-Body Parameter Added to a Service Method

**Description:** When the current TypeSpec adds one or more new optional non-body parameters (e.g. query, header, path) to an existing service method, the generator emits a hidden back-compat overload that matches the previous contract's signature and delegates to the new method, passing `default` for the new parameter(s). The behavior is **intentionally restricted to non-body parameters** because adding a body parameter typically reflects a schema change and is handled differently.

**Rules:**

- The previous method's parameters must appear, in the same relative order and matching by name and type, within the current method's parameters.
- Every "extra" parameter on the current method must be optional (i.e. have a default value).
- No "extra" parameter on the current method may be a body parameter; if any extra parameter is a body parameter, no back-compat overload is added.
- The back-compat overload is hidden via `[EditorBrowsable(EditorBrowsableState.Never)]` and has all default values stripped from its parameters to avoid ambiguous call sites.

**Example:**

Previous version of the client:

```csharp
public virtual ClientResult GetData(int p1, BinaryContent body, RequestOptions options = null);
public virtual Task<ClientResult> GetDataAsync(int p1, BinaryContent body, RequestOptions options = null);
```

Current TypeSpec adds an optional query parameter `p2`:

```typespec
op getData(@query p1: int32, @body body: SampleModel, @query p2?: boolean): string;
```

**Generated Client:**

The generated client includes the current methods (with the new optional `p2` parameter) and the hidden back-compat overloads that match the previous contract's signature. Required parameters come first, followed by optional parameters, with `RequestOptions` last — matching the [Azure SDK parameter ordering guidelines](https://azure.github.io/azure-sdk/dotnet_implementation.html#parameter-presence-and-ordering).

```csharp
// Current sync method generated from the updated TypeSpec.
public virtual ClientResult GetData(int p1, BinaryContent body, bool? p2 = default, RequestOptions options = null)
{
    // ... implementation ...
}

// Current async method generated from the updated TypeSpec.
public virtual async Task<ClientResult> GetDataAsync(int p1, BinaryContent body, bool? p2 = default, RequestOptions options = null)
{
    // ... implementation ...
}

// Back-compat sync overload matching the previous contract's signature.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual ClientResult GetData(int p1, BinaryContent body, RequestOptions options)
{
    return this.GetData(p1: p1, body: body, p2: default, options: options);
}

// Back-compat async overload matching the previous contract's signature.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual Task<ClientResult> GetDataAsync(int p1, BinaryContent body, RequestOptions options)
{
    return this.GetDataAsync(p1: p1, body: body, p2: default, options: options);
}
```

The back-compat overloads are hidden from IntelliSense via `[EditorBrowsable(EditorBrowsableState.Never)]`, have all default values stripped to avoid ambiguous call sites with the current methods, and delegate to the current method passing `default` for each new parameter.

#### Scenario: Value-Type Parameter Nullability Removed

**Description:** When a value-type parameter that was nullable in the last contract (`T?`) becomes non-nullable (`T`) in the current generation, the generator emits a hidden back-compat overload that reproduces the previous nullable signature and delegates to the current method, unwrapping the argument with `.Value`. The forwarded argument is guarded with `Argument.AssertNotNull` so a `null` argument produces a clear `ArgumentNullException` rather than an `InvalidOperationException` from `.Value`. This also covers extensible enums (which are read back from the last contract as structs), matched by fully-qualified type name.

**Example:**

Previous contract:

```csharp
public string GetData(string data, FileFormatType? value = default, bool? flag = default);
```

Current generation makes `value` non-nullable and required:

```csharp
public string GetData(string data, FileFormatType value, bool? flag = default);
```

**Generated Compatibility Overload:**

```csharp
[EditorBrowsable(EditorBrowsableState.Never)]
public string GetData(string data, FileFormatType? value = default, bool? flag = default)
{
    Argument.AssertNotNull(value, nameof(value));
    return this.GetData(data: data, value: value.Value, flag: flag);
}
```

**Key Points:**

- Only applies to value types (including extensible enums); reference-type nullability (`string?` vs `string`) cannot form distinct overloads and is not handled.
- Only the `T?` → `T` direction (removing nullability) is handled, not the widening direction.
- When the current parameter is required, the previous optional default is preserved so callers that omitted it still compile; the `AssertNotNull` guard turns a `null` argument into a clear `ArgumentNullException`.
- A `ref`/`out` parameter is not eligible (its value cannot be forwarded through `.Value`), so no overload is generated in that case.
- The overload is hidden via `[EditorBrowsable(EditorBrowsableState.Never)]`.

#### Scenario: Nullable Optional Parameter Became Required

**Description:** When a nullable parameter that was optional in the last contract (had a default value) becomes required in the current generation (same type, but no longer has a default), callers that omitted it no longer compile. The generator emits a hidden reduced-arity overload that drops the now-required parameter and delegates to the current method, supplying the parameter's previous default value.

**Example:**

Previous contract:

```csharp
public string GetData(string data, FileFormatType? value = default, bool? flag = default);
```

Current generation keeps `value` nullable but makes it required:

```csharp
public string GetData(string data, FileFormatType? value, bool? flag = default);
```

**Generated Compatibility Overload:**

```csharp
[EditorBrowsable(EditorBrowsableState.Never)]
public string GetData(string data, bool? flag = default)
{
    return this.GetData(data: data, value: default, flag: flag);
}
```

**Key Points:**

- Applies only to a single nullable parameter that changed from optional to required; the parameter's type is otherwise unchanged.
- The dropped parameter's type must differ from every other parameter's type so the reduced-arity overload's call sites stay unambiguous.
- The optionality of the remaining parameters is preserved, and the overload is hidden via `[EditorBrowsable(EditorBrowsableState.Never)]`.
- Unlike the nullability-removal scenario, the delegation passes the previous default — there is no `.Value` unwrap and no runtime throw.

---

### Packages Http Client Csharp Generator Docs Spector (`packages/http-client-csharp/generator/docs/spector.md`)

By default all tests under the [http-specs folder](https://github.com/microsoft/typespec/tree/main/packages/http-specs/specs/) will be generated. In order to get coverage for a test within one of the specs you must write a test case that executes the operation.

## Generating Spector libraries

Each spec will be generated when running `./eng/scripts/Generate.ps1` within the same folder structure it exists in the http-specs package. As an example [http/authentication/api-key](https://github.com/microsoft/typespec/tree/main/packages/http-specs/specs/authentication/api-key)
will live in the following folder inside the Spector test projects



The files that get generated here will only be stubbed public APIs. This is done to minimize the size of the repo and reduce PR diff noise when an internal implementation is modified which can potentially effect every model. Seeing the same diff in hundreds of files doesn't provide value it only introduces noise.

If you want to manually generate the non stubbed version you can call Generate.ps1 with the name of the project you want to generate and set Stubbed to false.
For example if you want to generate the non stubbed version of `http/authentication/api-key` you can do the following.

```powershell
./eng/scripts/Generate.ps1 http/authentication/api-key -Stubbed $false
```

## Writing Spector tests

Generating the stubs allows us write tests against the public API surface that will compile. To do this we add a test class in same folder structure although this time we will modify the casing slightly to match dotnet standards.



In this ApiKeyTests.cs we can write tests against the generated stubs like the following.

```C#
[SpectorTest]
public Task Valid() => Test(async (host) =>
{
    ClientResult response = await new ApiKeyClient(host, new ApiKeyCredential("valid-key"), null).ValidAsync();
    Assert.AreEqual(204, response.GetRawResponse().Status);
});
```

This test validates that we can successfully call the mock Spector service and verifies that we receive a successful response with code 204. Notice that we are using `SpectorTest` attribute instead of the standard NUnit `Test` attribute. This is because the test will not complete successfully against the stub and we must generate the full library before running the test.

The `SpectorTest` attribute will dynamically determine if the library is stubbed and mark the step as `Ignore` if it is. If it is not stubbed it will run the full test.

## Testing Spector scenarios

All of this is automated into a script called `./eng/scripts/Test-Spector.ps1`. This script will find all generated Spector projects and regenerate each of them without using the `StubLibraryGenerator`. It will then run dotnet test which will cause tests using the `SpectorTest` attribute to no longer be skipped. Finally it will restore the files back to the stubs if everything was successful and if not it will leave the files in place so you can investigate.

<details>
<Summary>Here is an example output for one library</Summary>

```
/* Detailed source-code truncated for AI context efficiency. */
```

</details>

## Debugging generation of a Spector library

If you want to debug the generation of one of the Spector libraries you can do this with the `StubLibraryGenerator`. There are launch settings for each Spector test which are already configured to use this generator.



The generator does not skip generating the methods bodies and xml docs it simply removes them before saving the files to disk. Therefore you can break at any point and debug any part of the full generation without needing to constantly flip the generator being used back and forth.

## Debugging Spector tests

To debug one of the `SpectorTest` you will need to generate the non stubbed library first by calling Generate.ps1 with Stubbed set to false.

```powershell
./eng/scripts/Generate.ps1 http/authentication/api-key -Stubbed $false
```

If you don't do this the test will be ignored by `SpectorTest` attribute since you cannot run a test when the library has no implementation.

## Problematic specs

The `./eng/scripts/Generate.ps1` script allows you to exclude a problematic spec by adding it to the `$failingSpecs` list. Ideally no specs should be here, but if we need to we can temporarily add items to the list and create tracking issues in github to remove them at a later time.

---

### Packages Http Client Java .Tspd Docs Usage (`packages/http-client-java/.tspd/docs/usage.md`)

### Prerequisite

Install [Node.js](https://nodejs.org/) 20 or above. (Verify by running `node --version`)

Install [Java](https://docs.microsoft.com/java/openjdk/download) 17 or above. (Verify by running `java --version`)

Install [Maven](https://maven.apache.org/download.cgi). (Verify by running `mvn --version`)

---

### Packages Http Server Js .Tspd Docs Footer (`packages/http-server-js/.tspd/docs/footer.md`)

## 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.

---

### Packages Http Server Js .Tspd Docs Header (`packages/http-server-js/.tspd/docs/header.md`)

: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.

---

### Packages Json Schema .Tspd Docs Usage (`packages/json-schema/.tspd/docs/usage.md`)

Add the `@jsonSchema` decorator to any types or namespaces you want to emit as JSON Schema.

```TypeSpec
import "@typespec/json-schema";

using JsonSchema;

@jsonSchema
namespace Example;

model Car {
  make: string;
  modelName: string;
}
```

---

### Packages Versioning .Tspd Docs Usage (`packages/versioning/.tspd/docs/usage.md`)

### Consuming versioning library from an emitter

#### Get the service representation at a given version

Versioning library works with projection to project the service at a given version.

```ts
// Get a list of all the different version of the service and the projections
const projections = buildVersionProjections(program, serviceNamespace);

for (const projection of projections) {
  const projectedProgram = projectProgram(program, projection.projections);
  // projectedProgram now contains the representation of the service at the given version.
}
```

#### Get list of versions and version dependency across namespaces

Versioning library works with projection to project the service at a given version.

```ts
const versions = resolveVersions(program, serviceNamespace);
// versions now contain a list of all the version of the service namespace and what version should all the other dependencies namespace use.
```

#### Consume versioning manually

If the emitter needs to have the whole picture of the service evolution across the version then using the decorator accessor will provide the metadata for each type:

- `getAddedOn`
- `getRemovedOn`
- `getRenamedFromVersion`
- `getMadeOptionalOn`

---

### Samples Client Csharp SampleService Package.Json (`docs/samples/client/csharp/SampleService/package.json`)

{
  "dependencies": {
    "@typespec/http-client-csharp": "1.0.0-alpha.20260310.2",
    "logging-plugin": "file:../plugins/logging"
  }
}

---

### Samples Client Csharp SampleService Tspconfig.Yaml (`docs/samples/client/csharp/SampleService/tspconfig.yaml`)

emit:
  - "@typespec/http-client-csharp"
options:
  "@typespec/http-client-csharp":
    emitter-output-dir: "{project-root}/SampleClient"

---

### Packages Http Client Csharp Eng Scripts Docs RegenPreview (`packages/http-client-csharp/eng/scripts/docs/RegenPreview.md`)

# RegenPreview.ps1

## Overview

`RegenPreview.ps1` is a PowerShell script that automates the process of building local generator packages and regenerating libraries for validation purposes. This script supports three modes:

- **Azure SDK Mode**: Regenerate Azure SDK for .NET libraries
- **OpenAI Mode**: Regenerate the OpenAI .NET library
- **Spector Mode**: Regenerate Azure spector test scenarios in azure-sdk-for-net

This script is designed to streamline the workflow for testing changes to the TypeSpec HTTP Client C# generator before submitting a pull request.

## Purpose

When making changes to the TypeSpec HTTP Client C# generator, it may be helpful to validate what the effects will be to generated libraries. This script automates the entire validation workflow by:

### Azure SDK Mode

1. Building local versions of the generator packages
2. Updating the Azure SDK for .NET repository to use these local packages
3. Regenerating all libraries (or specific libraries if `-Select` or `-Libraries` is specified)
4. Cleaning up all modifications after validation

### OpenAI Mode

1. Building local version of the unbranded generator package
2. Building local NuGet framework packages
3. Updating the OpenAI .NET repository's codegen configuration
4. Regenerating the OpenAI library using Invoke-CodeGen.ps1
5. Cleaning up all modifications after validation

### Spector Mode

1. Building local version of the unbranded generator package
2. Building local NuGet framework packages
3. Wiring the Azure generator in azure-sdk-for-net to use local packages
4. Running the Azure generator's Generate.ps1 to regenerate spector test scenarios
5. Cleaning up all modifications after validation

## Prerequisites

- **PowerShell 7.0 or later** (cross-platform: Windows, Linux, macOS)
- Node.js and npm installed
- .NET SDK installed
- Local clone of the `typespec` repository (unbranded generator)
- Local clone of the `azure-sdk-for-net` repository (for Azure SDK mode)
- Local clone of the `openai-dotnet` repository (for OpenAI mode)

## Usage

### Azure SDK Mode - Basic Usage (Regenerate All)

**Windows:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\path\to\azure-sdk-for-net"
```

**Linux/macOS:**

```powershell
./RegenPreview.ps1 -SdkLibraryRepoPath "/home/user/repos/azure-sdk-for-net"
```

This will:

- Clean and build the unbranded and Azure generators with local changes
- Regenerate **all** libraries automatically
- Restore all modified metadata files on success (ie. package.json, package-lock.json)

### OpenAI Mode - Basic Usage

**Windows:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\path\to\openai-dotnet"
```

**Linux/macOS:**

```powershell
./RegenPreview.ps1 -SdkLibraryRepoPath "/home/user/repos/openai-dotnet"
```

This will:

- Clean and build the unbranded generator with local changes
- Build and package NuGet framework packages
- Update root nuget.config with local NuGet source and packageSourceMapping
- Update codegen/package.json with local generator
- Regenerate codegen/package-lock.json with npm install
- Update OpenAI.Library.Plugin.csproj with local NuGet packages
- Regenerate the OpenAI library
- Restore all modified generator metadata files on success

**Note**: OpenAI mode is automatically detected when the repository path contains "openai-dotnet". The `-Select`, `-Azure`, `-Unbranded`, `-Mgmt`, and `-Libraries` parameters are not applicable in OpenAI mode.

### Parameters

#### `-SdkLibraryRepoPath` (Required)

The local file system path to your SDK repository (`azure-sdk-for-net` or `openai-dotnet`). When the path contains "openai-dotnet", the script automatically operates in OpenAI mode.

**Windows Example:**

```powershell
-SdkLibraryRepoPath "C:\repos\azure-sdk-for-net"
```

**Linux/macOS Example:**

```powershell
-SdkLibraryRepoPath "/home/user/repos/azure-sdk-for-net"
```

#### `-Select` (Optional)

**Azure SDK Mode only.** When specified, displays an interactive menu to select specific libraries to regenerate. If omitted, all libraries are regenerated automatically.

Can be combined with generator filter parameters (`-Azure`, `-Unbranded`, `-Mgmt`) to interactively select from a filtered subset.

Not applicable in OpenAI mode.

**Example:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Select
```

#### `-Azure` (Optional)

**Azure SDK Mode only.** When specified, only regenerates libraries using the Azure-branded generator (`@azure-typespec/http-client-csharp`).

Not applicable in OpenAI mode.

**Example:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Azure
```

#### `-Unbranded` (Optional)

**Azure SDK Mode only.** When specified, only regenerates libraries using the unbranded generator (`@typespec/http-client-csharp`).
Not applicable in OpenAI mode.

**Example:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Unbranded
```

#### `-Mgmt` (Optional)

**Azure SDK Mode only.** When specified, only regenerates libraries using the management plane generator (`@azure-typespec/http-client-csharp-mgmt`).

If no generator filter parameter is specified, all libraries are regenerated by default.

Not applicable in OpenAI mode.

**Example:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Mgmt
```

#### `-Libraries` (Optional)

**Azure SDK Mode only.** A comma-separated list of library names to regenerate. This parameter can be combined with `-Select` and generator filters (`-Azure`, `-Unbranded`, `-Mgmt`), but not with `-Spector`.

Not applicable in OpenAI mode.

**Example:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Libraries "Azure.ResourceManager.AppContainers, Azure.Data.AppConfig"
```

#### `-Spector` (Optional)

**Azure SDK Mode only.** When specified, regenerates the Azure spector test scenarios in azure-sdk-for-net instead of regenerating SDK libraries. This builds the local unbranded generator, wires it into the Azure generator, and runs the Azure generator's Generate.ps1 to regenerate spector test projects.

Mutually exclusive with `-Select`, `-Azure`, `-Unbranded`, `-Mgmt`, and `-Libraries`.

Not applicable in OpenAI mode.

**Example:**

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Spector
```

### Interactive Selection

When running with the `-Select` flag, the script presents an interactive menu listing all available libraries:

```
==================== LIBRARY SELECTION ====================
Found 28 libraries available for regeneration

Azure-branded libraries (@azure-typespec/http-client-csharp):
  [ 1] Azure.AI.VoiceLive                                  (ai)
  [ 2] Azure.Data.AppConfiguration                         (appconfiguration)
  ...

Unbranded libraries (@typespec/http-client-csharp):
  [12] Azure.AI.Projects                                   (ai)
  [13] Azure.AI.OpenAI                                     (openai)

Management plane libraries (@azure-typespec/http-client-csharp-mgmt):
  [14] Azure.ResourceManager.AgriculturePlatform           (agricultureplatform)
  [15] Azure.ResourceManager.ArizeAIObservabilityEval      (arizeaiobservabilityeval)
  ...

Enter library numbers to regenerate (comma-separated), 'all' for all libraries, or 'q' to quit:
Example: 1,3,5  or  1-4,7  or  all
```

**Selection Options:**

- Single library: `1`
- Multiple libraries: `1,3,5`
- Range of libraries: `1-4`
- Combination: `1-4,7,10`
- All libraries: `all`
- Quit: `q`

## How It Works

The script operates in two distinct modes based on the repository path provided.

### Azure SDK Mode

The script performs the following steps in sequence when the repository path points to `azure-sdk-for-net`:

### Step 0: Library Selection (Interactive Mode Only)

- Parses `Library_Inventory.md` in the azure-sdk-for-net repository
- Applies any generator filters if specified (`-Azure`, `-Unbranded`, `-Mgmt`)
- Displays available libraries grouped by generator type
- Prompts user to select which libraries to regenerate
- Skipped when `-Select` is not specified (non-interactive mode)

### Step 1: Build Unbranded Generator

- Runs `npm ci` to install dependencies
- Runs `npm run clean` to ensure a clean build
- Runs `npm run build` to build `@typespec/http-client-csharp`

### Step 2: Package Unbranded Generator

- Generates a local version string: `1.0.0-alpha.YYYYMMDD.hash`
- Updates `package.json` with the local version
- Runs `npm pack` to create a `.tgz` package
- Moves the package to the `debug` folder
- Restores original `package.json`

### Step 2.5: Build and Package NuGet Packages

- Generates NuGet packages for three generator framework projects:
  - `Microsoft.TypeSpec.Generator`
  - `Microsoft.TypeSpec.Generator.Input`
  - `Microsoft.TypeSpec.Generator.ClientModel`
- Uses Debug configuration with `--no-build` (reuses binaries from Step 1)
- Outputs `.nupkg` files to the `debug` folder
- In Azure SDK mode: Updates `Directory.Generation.Packages.props` and `NuGet.Config`
- In OpenAI mode: Proceeds to Step 3 (OpenAI regeneration)

---

### OpenAI Mode

When the repository path contains "openai-dotnet", the script switches to OpenAI mode and performs the following steps after Step 2.5:

#### Step 3: Update OpenAI Generator and Regenerate

**What the script does:**

- Updates `nuget.config` (at the root of the repo) with local NuGet package source
  - Adds the local debug folder as a package source
  - Updates `packageSourceMapping` to allow Generator packages from the local source (required for OpenAI's package source mapping configuration)
- Updates `codegen/package.json` with local unbranded generator dependency (`@typespec/http-client-csharp`)
  - Checks both `dependencies` and `devDependencies` sections for the package
  - Updates whichever section(s) contain the package to use `file:` protocol pointing to local `.tgz`
- Deletes `codegen/package-lock.json` to force regeneration with new dependencies
- Runs `npm install` in the codegen directory to regenerate the lock file with local dependencies
- Updates `codegen/generator/src/OpenAI.Library.Plugin.csproj` with local NuGet package version for `Microsoft.TypeSpec.Generator.ClientModel`
- Invokes `scripts/Invoke-CodeGen.ps1 -Clean` to regenerate the OpenAI library
- **On successful regeneration**, restores all modified artifacts:
  - `codegen/package.json`
  - `codegen/package-lock.json`
  - `nuget.config`
  - `codegen/generator/src/OpenAI.Library.Plugin.csproj`
- **On failure**, leaves all modified artifacts in place for debugging
- Displays success message and exits

**Note:** Filter parameters (`-Azure`, `-Unbranded`, `-Mgmt`, `-Select`, `-Libraries`) are not applicable in OpenAI mode and will cause an error if specified.

---

### Azure SDK Mode (continued)

In Azure SDK mode, the script continues with additional steps after Step 2.5:

### Step 3: Update and Build Azure Generator

- Updates the Azure generator's `package.json` to reference the local unbranded package using `file:` protocol
- Runs `npm run clean` to clear previous builds
- Runs `npm install --package-lock-only` to update the lock file with the new local dependency
- Runs `npm ci` for clean installation based on the updated lock file
- Builds the Azure generator with `npm run build`

### Step 4: Package Azure Generator

- Updates `package.json` with the local version (dependency already set in Step 3)
- Runs `npm pack` to create a `.tgz` package
- Moves the package to the `debug` folder
- Restores original `package.json` (after both Steps 3 and 4 complete)

### Step 5: Update eng Folder Artifacts

- Updates package.json artifacts in `azure-sdk-for-net/eng`:
  - `azure-typespec-http-client-csharp-emitter-package.json`
  - `azure-typespec-http-client-csharp-emitter-package-lock.json`
  - `http-client-csharp-emitter-package.json`
  - `http-client-csharp-emitter-package-lock.json`
- Uses a temporary directory to safely update the lock files
- These files control which generator versions are used during library regeneration

### Step 6: Update and Build Management Plane Generator

- Updates the management plane generator (`@azure-typespec/http-client-csharp-mgmt`) located in `azure-sdk-for-net/eng/packages/http-client-csharp-mgmt`
- Updates `package.json` to reference both:
  - Local Azure generator (`@azure-typespec/http-client-csharp`) using `file:` protocol
  - Local unbranded generator (`@typespec/http-client-csharp`) using `file:` protocol
- Runs `npm install` to install dependencies
- Runs `npm run clean` to ensure a clean build
- Runs `npm run build` to build the management plane generator
- Creates a local package with `npm pack`
- Updates eng folder emitter package artifacts:
  - `azure-typespec-http-client-csharp-mgmt-emitter-package.json`
  - `azure-typespec-http-client-csharp-mgmt-emitter-package-lock.json`
- Updates `Directory.Generation.Packages.props` in azure-sdk-for-net with `AzureGeneratorVersion` property
  - This version is used by management plane libraries that reference the `Azure.Generator` NuGet package
- This step is skipped if the management plane generator directory doesn't exist

### Step 7: Prepare Library List

- Confirms the list of libraries to regenerate
- Applies the `-Libraries` filter when specified
- When no `-Select` flag, loads all libraries from `Library_Inventory.md` including:
  - Data plane libraries using `@azure-typespec/http-client-csharp`
  - Data plane libraries using `@typespec/http-client-csharp`
  - Management plane libraries using `@azure-typespec/http-client-csharp-mgmt`
- In interactive mode (`-Select`), uses the previously selected libraries

### Step 8: Regenerate Libraries

- **Pre-Install tsp-client**: Runs `npm ci --prefix eng\common\tsp-client` once before parallel execution
  - Installs shared TypeSpec compiler tooling used by all libraries
  - Eliminates concurrent npm conflicts during parallel regeneration
- **Parallel Execution**: Uses PowerShell's `ForEach-Object -Parallel` to regenerate multiple libraries concurrently
- **Cross-Platform CPU Detection**:
  - Windows: Uses `Get-CimInstance` with `Win32_Processor`
  - Linux: Uses `nproc` command
  - macOS: Uses `sysctl -n hw.ncpu` command
- **Throttle Limit**: Automatically calculated as `(CPU cores - 2)` with a minimum of 1 and maximum of 8
- **Skip Redundant Installs**: Each parallel job uses `/p:SkipTspClientInstall=true` to skip re-installing tsp-client
- **Thread-Safe Progress**: Real-time updates showing `[completed/total] ✓/✗ LibraryName`
  - Success: Green with ✓
  - Failure: White with ✗ (red reserved for error details in final report)
- **Isolated Execution**: Each library regenerates in its own directory (no conflicts)
- Runs `dotnet build /t:GenerateCode /p:SkipTspClientInstall=true` in the library's project directory
- Automatically detects if the `.csproj` is in a `src` subdirectory
- Tracks success/failure for each library with colored output

### Step 9: Restore Artifacts (On Success Only)

If all libraries regenerate successfully, the script restores modified files:

- `eng/azure-typespec-http-client-csharp-emitter-package.json`
- `eng/azure-typespec-http-client-csharp-emitter-package-lock.json`
- `eng/http-client-csharp-emitter-package.json`
- `eng/http-client-csharp-emitter-package-lock.json`
- `eng/azure-typespec-http-client-csharp-mgmt-emitter-package.json`
- `eng/azure-typespec-http-client-csharp-mgmt-emitter-package-lock.json`
- `eng/packages/http-client-csharp/package-lock.json`
- `eng/packages/http-client-csharp-mgmt/package.json`
- `eng/packages/http-client-csharp-mgmt/package-lock.json`
- `eng/centralpackagemanagement/Directory.Generation.Packages.props`
- `NuGet.Config`

**Note:** If any libraries fail, artifacts are NOT restored, allowing you to debug the issue with the modified configuration intact.

## Shared Regeneration Helpers

The library discovery and parallel regeneration logic lives in `RegenPreview.psm1` so it can be reused outside of local validation runs:

| Function                        | Description                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Get-SdkLibrariesToRegenerate`  | Scans `sdk/` in azure-sdk-for-net and returns the libraries whose `tsp-location.yaml` references one of the TypeSpec C# emitter package json artifacts. Supports filtering by emitter (`-EmitterPackageJsonPaths`).                                                                                                                                                                                           |
| `Invoke-SdkLibraryRegeneration` | Pre-installs tsp-client, pre-builds the code generation plugin, and then regenerates the given libraries in parallel with `dotnet build /t:GenerateCode`. Supports `-ThrottleLimit` (defaults to 3x the logical processors, clamped to 4-12), `-NpmRegistry`, `-AdditionalBuildArgs`, `-SerialServiceDirectories` (service directories that must be regenerated one library at a time), and `-StopOnFailure`. |
| `Write-RegenerationReport`      | Prints the pass/fail summary and optionally writes the detailed JSON report. In CI mode, it also prints a human-readable JSON report.                                                                                                                                                                                                                                                                         |

### Error Handling

If the script encounters an error during pre-requisite steps (Steps 1-6), it will:

- Display the error message and stack trace
- Attempt to restore `NuGet.Config` to prevent leaving the repository in an inconsistent state
- Exit with code 1

## Output

### Debug Folder

All packaged artifacts are stored in the `debug` folder at the root of the unbranded generator:

- `typespec-http-client-csharp-{version}.tgz` - Unbranded generator npm package
- `azure-typespec-http-client-csharp-{version}.tgz` - Azure generator npm package
- `Microsoft.TypeSpec.Generator.{version}.nupkg` - Core generator NuGet package
- `Microsoft.TypeSpec.Generator.Input.{version}.nupkg` - Input models NuGet package
- `Microsoft.TypeSpec.Generator.ClientModel.{version}.nupkg` - Client model NuGet package
- `regen-report.json` - Detailed JSON report of regeneration results (written to the ADO artifact staging
  directory during CI runs)

### Console Output

The script provides colored console output with:

- **Cyan**: Step headers and section dividers
- **Yellow**: Important information (versions, library counts, warnings)
- **Gray**: Detailed command execution and file operations
- **Green**: Success messages
- **Red**: Error messages and failed libraries
- **White**: Library names during regeneration

### Regeneration Report

After regeneration completes, a summary report is displayed:

```
==================== REGENERATION REPORT ====================
Total Libraries: 3
Passed: 2
Failed: 1
Execution Time: 00:02:45

PASSED LIBRARIES:
  ✓ Azure.AI.VoiceLive (ai)
  ✓ Azure.AI.Projects (cognitiveservices)

FAILED LIBRARIES:
  ✗ Azure.Messaging.EventGrid.Namespaces (eventgrid)
    Error: Generation failed with exit code 1
    Details: ...

=============================================================
Detailed report saved to: C:\...\debug\regen-report.json
```

In ADO CI runs, the detailed JSON report is written to the artifact staging directory instead and is
also printed to the console in human-readable JSON. If any library fails to regenerate, later regeneration
batches are marked as skipped and the script exits with an error after printing the report. Local runs keep
the existing behavior: all regeneration batches run, and any library failures are reported as warnings at
the end.

## Common Scenarios

### Scenario 1: Test OpenAI Library Changes

```powershell
# You made changes to the unbranded generator that affect OpenAI
# Regenerate the OpenAI library to validate your changes
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\openai-dotnet"
```

### Scenario 2: Test a Small Change Quickly (Azure SDK)

```powershell
# You want to test Azure generator changes on specific libraries only
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Libraries "Azure.ResourceManager.AppContainers, Azure.Data.AppConfig"
```

### Scenario: Full Validation Before PR

```powershell
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net"
```

### Scenario 4: Regenerate Azure Spector Test Scenarios

```powershell
# Validate that local changes don't break Azure spector test scenarios
.\RegenPreview.ps1 -SdkLibraryRepoPath "C:\repos\azure-sdk-for-net" -Spector
```

---

### Website Src Content Docs Release Notes Cadl Typespec Migration (`website/src/content/docs/release-notes/cadl-typespec-migration.md`)

---
title: Cadl to TypeSpec rename completed in March 2023 release
---

As you may recall from our previous email to partners, we are renaming the product as it becomes more mature, stable and one step closer to release.

With the 2023-03-13 release, We are pleased to announce that we have completed the process of changing the name of our product from **Cadl** to **TypeSpec**. This marks another important milestone. The new name better aligns with the functionality and benefits of the product, and we believe it will make it easier for our customers to understand and remember.

We understand that change can be challenging, and we appreciate your patience and support during this process.

## Name Changes

- Packages:
  - NPM package scope:
    - @cadl-lang/[xx] -> @typespec/[xx]

  - Package names

| Old Package Name    | Old Namespace        | New Package Name   | New Namespace   |
| ------------------- | -------------------- | ------------------ | --------------- |
| @cadl-lang/compiler | using Cadl;          | @typespec/compiler | using TypeSpec; |
| @cadl-lang/rest     | using Cadl.Http;     | @typespec/http;    | using Http;     |
| @cadl-lang/rest     | using Cadl.Rest;     | @typespec/rest     | using Rest;     |
| @cadl-lang/openapi  | using Cadl.OpenApi;  | @typespec/openapi  | using OpenAPI;  |
| @cadl-lang/openapi3 | using Cadl.OpenApi3; | @typespec/openapi3 | using OpenAPI3; |

- File extension:
  - `.cadl` -> `.tsp`

- Configuration file:
  - `cadl-project.yaml` -> `tspconfig.yaml`

- CLI
  - `npx cadl compile .` -> `npx tsp compile .`

- Compiler JS APIs
  - All artifacts with `*Cadl*` in the name have been updated to `*TypeSpec*`. However, aliases have been created with older `*Cadl*` name with `@deprecated` flag.
- Noteable changes:
  - @cadl-lang/rest was split into two packages, @typespec/rest and @typespec/http

- Back-compatibility
  - `.cadl` files are continue be recognized by compiler.
  - `cadl-project.yaml` is still supported if `tspconfig.yaml` not found

## Migration tool

An experimental migration tool has been introduced to take care of many of the manual migration steps. Just execute following command in your TypeSpec folder.

```bash
npx @typespec/migrate
```

If you would like execute from a different folder or don't have a `package.json` that indicates compiler package versions, please see command line options:

```bash
npx @typespec/migrate --help
```

The migration tool will perform following steps:

- Rename `cadl-project.yaml` to `tspconfig.yaml`.
- Update `tspconfig.yaml` format to new `emit` schema if necessary.
- Rename `.cadl` files to `.tsp`.
- Update `import` and `using` statements in any `.tsp` files
- Update `package.json` with new package name and versions.

---

### Website Src Content Docs Release Notes Release 2022 07 08 (`website/src/content/docs/release-notes/release-2022-07-08.md`)

---
title: July 2022
releaseDate: 2022-07-08
---

This release contains **breaking changes**

- Emitter options normalized to use kebab-case instead of camelCase.
- `@serviceHost` decorator replaced by `@server` decorator
- Versioning decorators now use enumerated values instead of strings

## Emitter options

This release brings a stricter option definition for emitters and requires usage of those options to be specified with the fully qualified name to prevent conflicts.
All options have also been renamed to match `kebab-case` naming.
The options can also be specified via the `tspconfig.yaml` file.

### Migrating Command Line Scripts

If you had for example `--option operationPollingLocation=tenant`

1. Use `tspconfig.yaml` project file **Recommended**

   If you don't have that file yet, create it next to `package.json`, this file can be used to configure the emitters.

   ```yaml
   emitters:
     <fully-qualified-emitter-package-name>:
         <optionName>: <optionValue>

   # For example
   emitters:
     @typespec/openapi3:
       output-file: ./openapi.json
   ```

2. Via the `--option` flag

   You can still use the `--option` flag but you'll need to specify the fully qualified name of the option.

   ```bash
   --option @<emitter-package>.<optionName>=<optionValue>

   # For example
   --option @typespec/openapi3.output-file=openapi.json
   ```

#### Renamed Emitter Options

| Before                 | Now           |
| ---------------------- | ------------- |
| **@typespec/openapi3** |
| `outputFile`           | `output-file` |

## `@serviceHost` decorator replaced with `@server` decorator

The `@serviceHost` decorator that decorated the root namespace was used to specify the domain name of the base service endpoint. This functionality has been replaced by the `@server` decorator, which allows specifying full and parametrized Uris for the service endpoint, as described [here](https://typespec.io/docs/libraries/http/#service-definition-and-metadata)

### Before

```typespec
@serviceHost("example.com")
namespace MyService;
```

### After

```typespec
@server("https://example.com")
namespace MyService;
```

## Versioning uses enums instead of strings

Versions must now be specified using string-valued enumerations, and each of the versioning decorators must reference an enum value rather than using the version string directly.

```typespec
// Before
@versioned("2021-01-12" | "2022-01-15-preview")
namespace Api;

// After
@versioned(Versions)
namespace Api;

enum Versions { v2021_01_12: "2021-01-12", v2022_01_15_preview: "2022-01-15-preview" }
```

```typespec
// Before
@added("2022-01-15-preview")
model Foo {}

// After
@added(Versions.v2022_01_15_preview)
model Foo {}
```

---

### Website Src Content Docs Release Notes Release 2022 08 10 (`website/src/content/docs/release-notes/release-2022-08-10.md`)

---
title: August 2022
releaseDate: 2022-08-10
---

This release contains **breaking changes**

- Operation parameters without decorators
- OkResponse is no longer a template
- Route resolution changes
- Remove `Map` type
- `@path` may not decorate optional properties or parameters without a default value

## Operation parameters without decorators

A single undecorated (not marked `@query`, `@header`, `@body` or `@path`) operation parameter will now become a property of the request body rather than have its type define the request body. This allows defining the body with multiple unannotated parameters, which can include unannotated properties that are spread into parameters. (Previously, more than one unannotated parameter was an error.)

For example, the following used to define a request body of type `string`, but now defines a request body that is an object with a property named `body` of type string.

```typespec
op create(body: string): void;
```

To get the previous behavior, the parameter now needs to be explicitly marked with `@body`:

```typespec
op create(@body body: string): void;
```

## OkResponse is no longer a template

Previously, OkResponse took an argument for the body type. Now it is a simple model like the other XxxResponse types. Alone, it implies a status code of 200 with no body.

Since 200 is the default status code for non-empty bodies, you can usually replace `OkResponse<T>` with simply `T`.

```typespec
op get(id: string): OkResponse<Pet>;
```

Can be:

```typespec
op get(id: string): Pet;
```

In certain situations where the body type is not (necessarily) a model, you will need to use the new `Body<T>` type. For example.

```typespec
op list(): OkResponse<Pet[]>;
```

Can become:

```typespec
op list(): OkResponse & Body<Pet[]>;
```

Since 200 status code is used by default, this could also be:

```typespec
op list(): Pet[];
```

Generic models based on `OkResponse<T>` may also require `Body<T>`. For example:

```typespec
model MyResponse<T> {
  ...OkResponse<T>;
  @header example: string;
}
```

Since T is not constrainted to be a model, it might be an intrinsic type, an array, or the like, the template should be changed to use `Body<T>`:

```typespec
model MyResponse<T> {
  ...OkResponse;
  ...Body<T>;
  @header example: string;
}
```

In general, the prior `OkResponse<T>` is equivalent to `OkResponse & Body<T>` now or, equivalently, `{ ...OkResponse, ...Body<T> }`. In practice there are many situations where you can leave out OkResponse altogether and use plain `T` rather than `Body<T>`.

See also https://typespec.io/docs/libraries/http/#request--response-bodies

## Route resolution changes

Resolving operation routes now follows the following logic:

- if there is a service namespace specified
  - only emit the operations and interfaces under that namespace(recursively)
- if not:
  - only emit the operations and interfaces defined at the root (DO NOT look into namespaces)

### Action if applicable

- If a TypeSpec spec used a service namespace without `@serviceTitle` add the `@serviceTitle` decorator to the service namespace, otherwise no routes will be emitted.
- If a TypeSpec spec contains service namespaces that are not child namespaces of the service namespace, move these namespaces under the service namespace.

### Cases

#### Operation at the root

```typespec
op test(): void;
```

✅ Stay the same

| Before  | After   |
| ------- | ------- |
| `["/"]` | `["/"]` |

#### Operation in namespace (not service namespace)

```typespec
namespace DemoService;

op test(): void;
```

⚠️ Output stays the same but add warning that no routes are emitted

| Before | After |
| ------ | ----- |
| `[]`   | `[]`  |

#### Operation in namespace (not service namespace) with @route

```typespec
namespace DemoService;

@route("/")
op test(): void;
```

⚠️ Now the same as previous case, no routes emitted and emit warning

| Before  | After |
| ------- | ----- |
| `["/"]` | `[]`  |

##### Resolve by adding the `@serviceTitle` decorator

Add `@serviceTitle` to the namespace

```typespec
@serviceTitle("DemoService")
namespace DemoService;

@route("/")
op test(): void;
```

#### Operation in service namespace

```typespec
@serviceTitle("My Service")
namespace Foo;

op test(): void;
```

✅ Stay the same

| Before  | After   |
| ------- | ------- |
| `["/"]` | `["/"]` |

#### Operation in namespaces other than the service namespace

```typespec
import "@typespec/rest";

using Http;

@serviceTitle("My Service")
namespace Foo {
  @route("in-service")
  op test(): void;
}

namespace MyLib {
  @route("my-lib")
  op test(): void;
}
```

⚠️ Other namespace routes are not included anymore

| Before                      | After             |
| --------------------------- | ----------------- |
| `["/in-service", "my-lib"]` | `["/in-service"]` |

##### Resolve by making additional namespaces children of the service namespace

Make any added namespaces children of the service namespace

```typespec
import "@typespec/rest";

using Http;

@serviceTitle("My Service")
namespace Foo {
  @route("in-service")
  op test(): void;
}

namespace Foo.MyLib {
  @route("my-lib")
  op test(): void;
}
```

## Remove Map type

`Map` type was removed. Usages of `Map<string, T>` can be replaced with new type `Record<T>`. Other usages of `Map` may be replaced with `object`.

### Map using string key type

```typespec
model Foo {
  options: Map<string, string>;
}
```

#### Replace with `Record<T>`

```typespec
model Foo {
  options: Record<string>;
}
```

### Map using non-string key type

```typespec
model Foo {
  options: Map<int32, string>;
}
```

#### Replace with `object`

```typespec
model Foo {
  options: object;
}
```

## `@path` may not decorate optional properties or parameters without a default

Properties and parameters marked with the `@path` decorator should be required, but may be optional if they have a default value

### optional path parameters

```typespec
model Foo {
  @path
  name?: string;
}
```

Was a bad practice, but was allowed in previous versions. This will now throw an error diagnostic.

### Resolve by making the property required

```typespec
model Foo {
  @path
  name: string;
}
```

### Resolve by adding a default value

```typespec
model Foo {
  @path
  name?: string = "singleton";
}
```

---

### Website Src Content Docs Release Notes Release 2022 09 07 (`website/src/content/docs/release-notes/release-2022-09-07.md`)

---
title: September 2022
releaseDate: 2022-09-07
---

This release contains **breaking changes**:

- **`Api`**: Remove `Type` suffix
- **`TypeSpec`**: Rename `Page` to `CollectionWithNextLink`
- **`Api`**: `Enum.members` change typed from `EnumMember[]` to `Map<string, EnumMember>`
- **`TypeSpec`** **`Api`**: **Deprecation** of `@consumes` `@produces` decorators

## **[API]** `Type` suffix removed from most `Type`s

The following types have been renamed in the compiler API:

- `ModelType` -> `Model`
- `ModelTypeProperty` -> `ModelProperty`
- `InterfaceType` -> `Interface`
- `EnumType` -> `Enum`
- `EnumMemberType` -> `EnumMember`
- `TemplateParameterType` -> `TemplateParameter`
- `NamespaceType` -> `Namespace`
- `OperationType` -> `Operation`
- `StringLiteralType` -> `StringLiteral`
- `NumericLiteralType` -> `NumericLiteral`
- `BooleanLiteralType` -> `BooleanLiteral`
- `TupleType` -> `Tuple`
- `UnionType` -> `Union`
- `UnionTypeVariant` -> `UnionVariant`
- `ProjectionType` -> `Projection`

Update uses of the type names on the left with the type names on the right. The old names can still be used but they are deprecated and may be removed from a future release.

## [TYPESPEC] Rename `Page` to `CollectionWithNextLink`

In library `@typespec/rest` in `TypeSpec.Rest.Resources` namespace the `Page` model was renamed to `CollectionWithNextLink`.
This resolve an issue with `Page` being to generic of a name for this very opinionated model.

Before

```typespec
op test(): Page<MyResource>;
```

Rename to

```typespec
op test(): CollectionWithNextLink<MyResource>;
```

## **[Api]** `Enum.members` change to `Map` [#953](https://github.com/microsoft/typespec/pull/953)

Changed the type of the `members` property of `Enum` from `EnumMember[]` => `Map<string, EnumMember>`

```diff
-members: EnumMember[];
+members: Map<string, EnumMember>
```

## [TypeSpec] [Api] **Deprecation**: `@consumes` `@produces`

Consumption of the data set by decorators was already removed in a previous release. Using them was a no-op.

The following are deprecated and will be removed in next release.

- `@consumes`
- `@produces`
- `getConsumes`
- `getProduces`

Alternative is to use a `@header contentType: <contentType>` property on the operation parameters or return type

---

### Website Src Content Docs Release Notes Release 2022 10 12 (`website/src/content/docs/release-notes/release-2022-10-12.md`)

---
title: October 2022
releaseDate: 2022-10-12
---

This release contains **breaking changes**:

- **`TypeSpec`**: Cannot `extends` or `is` a model expression via alias
- **`Api`**: Removed `createProgram` and changed `compile` parameter order
- **`TypeSpec`** **Deprecation** `@service` decorator replacing `@serviceTitle` and `@serviceVersion`
- **`TypeSpec`** **`Api`**: Move `@discriminator` to compiler

## [TypeSpec] Cannot `extends` or `is` a model expression via alias [PR 1004](https://github.com/microsoft/typespec/pull/1004)

Using model expression for `is` or `extends` directly was already forbidden.


```typespec
model IsModelExpr is {bar: string} {}

model ExtendsModelExpr extends {bar: string} {}
```

The following workaround was however tolerated. This PR remove this functionality.


```typespec
alias ModExpr = {bar: string};
model IsModelExprWAlias is ModExpr {}

model ExtendsModelExprWAlias extends ModExpr {}
```

Use a named model instead of an alias.

## [API] Removed `createProgram` and changed `compile` parameter order

`createProgram` has been removed in favor of `compile`. The new compile has the same parameter as `createProgram`

```ts
// Before
createProgram(host, "main.tsp);

// After
compile(host, "main.tsp");
```

`compile` api was changed to match the same order as old `createProggram`

```ts
// Before
compile("main.tsp", host);

// After
compile(host, "main.tsp");
```

## [TypeSpec] Deprecation: @service decorator replacing `@serviceTitle` and `@serviceVersion`

- `@serviceTitle` has been deprecated
- `@serviceVersion` has been deprecated

```typespec
// Before
@serviceTitle("Pet Store")
@serviceVersion("v1")
namespace PetStore;

// After
@service(#{"Pet Store", version: "v1"})
namespace PetStore;
```

This allows to specify the service namespace without any title or version

```typespec
@service
namespace PetStore;
```

## [TypeSpec] [Api] Move `@discriminator` to compiler

The `@discriminator` has been moved to the compiler. This means that if you were using the fully qualified name to reference the decorator `@TypeSpec.Rest.disriminator` it should be changed to `@discriminator`

**No changes**

```typespec
using Rest;

@disriminator("kind")
model Pet {}
```

**Before**

```typespec
@TypeSpec.Rest.disriminator("kind")
model Pet {}
```

**After**

```typespec
@disriminator("kind")
model Pet {}
```

### Change to api

the `getDiscriminator` accessor has also been removed into the compiler.

Before


```ts
import { getDiscriminator } from "@typespec/rest";
```

After


```ts
import { getDiscriminator } from "@typespec/compiler";
```

---

### Website Src Content Docs Release Notes Release 2022 12 07 (`website/src/content/docs/release-notes/release-2022-12-07.md`)

---
title: December 2022
releaseDate: 2022-12-07
---

:::caution
This release contains **breaking changes**
:::

## New features

### Decorator signature help

With the decorator signature `extern dec` added in previous release and the doc comment support added in this version the IDE is able to provide a signature help for decorators



## New `scalar` type

:::caution
This is a breaking change [see details here](#change-to-typespec-intrinsic-models)
:::

This release introduce a new [scalar](../language-basics/scalars.md) type meant to represent what were previously models with no properties actually representing an scalar value.

```typespec
scalar uuid extends string;
```

## Emitter options interpolation and standardization

Emitter options are not able to interpolate other values. See [details](../handbook/configuration/configuration.md#variable-interpolation)

```yaml
output-dir: {cwd}/generated
options:
  @typespec/openapi3:
    emitter-output-dir: {output-dir}/openapi3
```

## Breaking changes

### `TypeSpec` `Api` `Compiler` Moved TypeSpec intrinsic types to a new Type `scalar`

A new type has been introduced to TypeSpec in order to differentiate scalar from structured models types. Those new types can be declared using `scalar` and can extend another scalar using `extends`.

#### Change to TypeSpec intrinsic models

All of TypeSpec intrinsic models have been updated to be `scalar` types instead of `model`. In most cases this shouldn't affect a spec but if you are defining a custom model that `is` one of the intrinsic types you'll have to update it

Before

```
model MyStr is string;
```

After

```
scalar MyStr extends string;
```

##### Migration script

The following script can be used to automatically migrate previous usages.

```typespec
npx @typespec/migrate
```

#### Change to Compiler API

Removed:

- `getIntrinsicModelName`: Check it is a std type with `program.checker.isStdType(type)` and then use the `type.name` otherwise look for `type.baseScalar`
- `isIntrinsic`: Check it is a std type with `program.checker.isStdType(type)` or just remove the check if goal was to omit intrinsic types from models.

Migration:

1. Add a new switch to handle the new `scalar` type
2. To resolve a scalar type, check if its a std type using `program.checker.isStdType(type)`
3. If yes, do the same behavior has before with `getIntrinsicModelName`
4. If not, call `scalar.baseScalar` and repeat step 2.

### `API` - Change to `onEmit` signature

The signature of `onEmit` has been updated to accommodate for changes to the emitter options

**Before**

```ts
export function $onEmit(program: Program, options: MyEmitterOptions);
```

**Now**

```ts
export function $onEmit(context: EmitContext);
```

Access properties

| Before                  | Now                                                                                                             |
| ----------------------- | --------------------------------------------------------------------------------------------------------------- |
| `program`               | `context.program`                                                                                               |
| `options`               | `context.options`                                                                                               |
| `options["output-dir"]` | `context.emitterOutputDir` [See details](#typespec-api-emitter-option-output-dir-renamed-to-emitter-output-dir) |

### [TypeSpec] [Api] Emitter option `output-dir` renamed to `emitter-output-dir`

The option has been renamed for all emitters as `emitter-output-dir` is now managed in the compiler
Before

```yaml
emitters:
  my-emitter:
    output-dir: /path/to-output-dir
```

Now

```yaml
emitters:
  my-emitter:
    emitter-output-dir: {output-dir}/for-this-emitter
#                        ^ can now reference the common output-dir
```

### Change to api

**Before**

```ts
export function $onEmit(program: Program, options: MyEmitterOptions) {
  const outputDir = options["output-dir"];
}
```

**Now**

```ts
export function $onEmit(context: EmitContext) {
  const outputDir = context.emitterOutputDir;
}
```

### `API > @typespec/compiler` Multiple services per typespec specs are now allowed making a service accessor obsolete.

The following functions have been deprecated

```ts
export function getServiceTitle(program: Program): string;
export function getServiceVersion(program: Program): string;
export function getServiceNamespace(program: Program): Namespace;
export function getServiceNamespaceString(program: Program): string | undefined;
export function setServiceNamespace(program: Program, namespace: Namespace);
```

and replaced with

```ts
export interface ServiceDetails {
  title?: string;
  version?: string;
}
export interface Service extends ServiceDetails {
  type: Namespace;
}

export function listServices(program: Program): Service[];
export function getService(program: Program, namespace: Namespace): Service | undefined;
export function isService(program: Program, namespace: Namespace): boolean;

export function addService(program: Program, type: Namespace, details?: ServiceDetails);
```

Other changes to the service resolution:

- Title won't be defaulted to `(title)`
- Version won't be defaulted to `0000-00-00`
- Service namespace won't be defaulted to global namespace

| Before                               | To add support for multi serviceF                                                            |
| ------------------------------------ | -------------------------------------------------------------------------------------------- |
| `getServiceNamespace(program)`       | `listServices(program)` to get all services                                                  |
| `getServiceNamespaceString(program)` | `getNamespaceName(service.type)` is where service is `getService(program, serviceNamespace)` |
| `getServiceTitle(program)`           | `service.title` where service is `getService(program, serviceNamespace)`                     |
| `getServiceVersion(program)`         | `service.version` where service is `getService(program, serviceNamespace)`                   |

### `TypeSpec` Directives can no longer be placed in certain contexts.

For example, this is no longer valid:

```typespec
model M<
#suppress example
T
> {}
```

And will now result in an error "Cannot place directive on template parameter".

Move such directives up to the nearest statement, interface operation, model property, operation parameter, union variant, or enum member.

For the above example, that would be:

```
#suppress example
model M<T> {}
```

## Deprecations

:::caution
Deprecated items will be removed in 2 release cycle.
:::

### `TypeSpec > @typespec/rest` - `@segmentSeparator` is deprecated. The `@actionSeparator` decorator should be used instead.

Before

```typespec
@autoRoute
namespace Things {
  @action
  @segmentSeparator(":")
  @put
  op customAction1(
    @segment("things")
    @path
    thingId: string,
  ): string;
}
```

After:

```typespec
@autoRoute
namespace Things {
  @action
  @actionSeparator(":")
  @put
  op customAction1(
    @segment("things")
    @path
    thingId: string,
  ): string;
}
```

### `TypeSpec` Deprecated `uri` being replaced by `url`

Before:

```typespec
model Server {
  endpoint: uri;
}
```

Now:

```typespec
model Server {
  endpoint: url;
}
```

### `Config` - Deprecated `emitters` property in the `tspconfig.yaml`

The `emitters` property of the configuration file has been deprecated and replaced by 2 new properties making it consistent with the CLI

Before:

```yaml
emitters:
  "@typespec/openapi3":
    output-file: openapi3.json
  other-emitter: true
```

After:

```yaml
emit:
  - "@typespec/openapi3"
  - "other-emitter"
options:
  @typespec/openapi3:
    output-file: openapi3.json
```

---

### Website Src Content Docs Release Notes Release 2023 01 12 (`website/src/content/docs/release-notes/release-2023-01-12.md`)

---
title: January 2023
releaseDate: 2023-01-12
---

:::caution
This release contains **breaking changes**
:::

## Breaking Changes

### `@typespec/openapi3` Default output-file is `openapi.yaml`

As the openapi3 emitter added support for serializing the openapi document to yaml it changed the default to emit yaml to `openapi.yaml`.

```yaml
options:
  @typespec/openapi3:
     file-type: json
```

or alternatively specify the name of the file you'd want

```yaml
options:
  @typespec/openapi3:
     output-file: custom.json
```

### [API] Templated operation inside interface

This breaking change affects libraries and emitters

- `templateArguments` property on templated type is deprecated and has been replaced with more detailed `templateMapper`

  If you where you using the `templateArgument` to find out if something was a template instance change

  ```ts
  type.templateArguments.length > 0;
  ```

  to

  ```ts
  isTemplateInstance(type);
  ```

- Interfaces might have some templated operations

  If blindly including all operations in an interface you might need to make sure the operation is not a template declaration first.

  For example with the following tsp code:

  ```typespec
  interface Factory {
    read<T>(): T;
    ping(): void;
  }
  ```

The emitter probably only wants to include the `ping()` operation but ignore read(). The `isTemplateDeclaration` helper can be used to filter out the template operations.

---

### Website Src Content Docs Release Notes Release 2023 02 07 (`website/src/content/docs/release-notes/release-2023-02-07.md`)

---
title: February 2023
releaseDate: 2023-02-07
---

:::caution
This release contains **breaking changes**
:::

## New Features

### Emitter Framework

The new emitter framework makes it simpler to build emitters from TypeSpec to other assets. It provides an easy way to handle TypeSpec types and provides a template for asset emitters to spell out the emitter tasks. It provides helpers to solve many difficult problems, including:

- Constructing references between types
- Handling circular references
- Propagating type context based on containers or references
- Class-based inheritance to encourage reuse and specialization of existing emitters

Details are available on the documentation website or in the [repository documentation] (https://github.com/microsoft/typespec/blob/main/docs/extending-typespec/emitter-framework.md).

### Cli support for emitters in development

Use the path to the emitter to specify emitter options, rather than the emitter name.

### Allow `@autoroute` and `@route` to be used together

Provide standard rules for combining `@route` and `@autoroute` decorators

- Allow `@route` applied to an operation to override route settings from the interface
- Allow `@route` on an operation to prepend the paths provided by `@autoroute`

### Simplified versioning dependencies

Introduced the `@useDependency` decorator to replace `@versionedDependency` decorator. Simplify dependencies between versioned namespaces, by allowing each version to be decorated with the appropriate versioned dependency, rather than requiring the user to construct a dependency map.

## Breaking Changes

Breaking changes in this release resulted from removal of previously decorated types and functions, including:

- `uri` scalar removed. Use the `url` scalar instead.
- Removed deprecated metadata types with the 'type' suffix.
  - Use `Enum` instead of `EnumType`
  - Use `EnumMember` instead of `EnumMemberType`
  - Use `Interface` instead of `InterfaceType`
  - Use `Model` instead of `ModelType`
  - Use `ModelProperty` instead of `ModelTypeProperty`
  - Use `Namespace` instead of `NamespaceType`
  - Use `Operation` instead of `OperationType`
  - Use `Tuple` instead of `TupleType`
  - Use `Union` instead of `UnionType`
- Removed `Map<K, V>` type, use `Record<V>` instead
- Removed `@serviceTitle` and `@serviceVersion` decorators. Use the `@service` decorator instead.
- Removed helper and accessor functions associated with `@serviceTitle` and `@serviceVersion` decorators
  - Replace `getServiceNamespace`, `getServiceTitle`, `getServiceVersion`, and `getServiceNamespaceString` with `getService` or `listServices`
  - Replace `setServiceNamespace` with `addService`
- Removed `@segmentSeparator`, use `@actionSeparator` instead
- Removed `@produces` and `@consumes` decorators. Use `@header contentType: <ContentType>` instead in the operation return type
- Removed `getSegmentSeparator` function. Use `getActionSeparator` instead
- Removed `getProduces` and `getConsumes` functions. Use `getContentTypes` instead

## Deprecations

### Deprecates the `@versionedDependency` decorator in favor of the `@useDependency` decorator

For versioned libraries, `@useDependency` is applied to the version enum members

#### Before (versioned namespace)

```typespec
@armProviderNamespace
@service(#{ title: "Microsoft.Observability" })
@versionedDependency(
  [
    [Microsoft.Observability.Versions.v2021_06_13_preview, Azure.Core.Versions.v1_0_Preview_2],
    [Microsoft.Observability.Versions.v2022_04_30_preview, Azure.Core.Versions.v1_0_Preview_2]
  ]
)
@versionedDependency(
  [
    [
      Microsoft.Observability.Versions.v2021_06_13_preview,
      Azure.ResourceManager.Versions.v1_0_Preview_1
    ],
    [
      Microsoft.Observability.Versions.v2022_04_30_preview,
      Azure.ResourceManager.Versions.v1_0_Preview_1
    ]
  ]
)
@versioned(Versions)
namespace Microsoft.Observability;

interface Operations extends Azure.ResourceManager.Operations {}

enum Versions {
  v2021_06_13_preview: "2021-06-13-preview",
  v2022_04_30_preview: "2022-04-30-preview",
}
```

#### After (Versioned namespace)

```typespec
@armProviderNamespace
@service(#{ title: "Microsoft.Observability" })
@versioned(Versions)
namespace Microsoft.Observability;

interface Operations extends Azure.ResourceManager.Operations {}

enum Versions {
  @useDependency(Azure.Core.Versions.v1_0_Preview_2, Azure.ResourceManager.Versions.v1_0_Preview_1)
  v2021_06_13_preview: "2021-06-13-preview",

  @useDependency(Azure.Core.Versions.v1_0_Preview_2, Azure.ResourceManager.Versions.v1_0_Preview_1)
  v2022_04_30_preview: "2022-04-30-preview",
}
```

For unversioned libraries that reference versioned libraries, simply replace `@versionedDependency` with `@useDependency`

#### Before (unversioned namespace using versioned library)

```typespec
@service(#{ title: "Microsoft.EnvelopeTest", version: "2021-09-21-preview" })
@versionedDependency(Azure.ResourceManager.Versions.v1_0_Preview_1)
@armProviderNamespace
namespace Microsoft.EnvelopeTest;
```

#### After (unversioned namespace using versioned library)

```typespec
@service(#{ title: "Microsoft.EnvelopeTest", version: "2021-09-21-preview" })
@useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1)
@armProviderNamespace
namespace Microsoft.EnvelopeTest;
```

---

### Website Src Content Docs Release Notes Release 2023 03 13 (`website/src/content/docs/release-notes/release-2023-03-13.md`)

---
title: March 2023
releaseDate: 2023-03-13
---

:::caution
This release contains **breaking changes**

Please see [Cadl to TypeSpec rename and migration FAQ](./cadl-typespec-migration.md)
:::

## New Features

### Add--config option

Enable specifying path to configuration file

### Allow escaping identifiers using backticks

Identifiers may contain reserved words or non-standard characters when surrounded with backticks (`), for example:

```typespec
op `op`(): void;
```

### Correct Order of Application for augment decorators

Augment decorators applied last

### Added migration script for specs using Cadl

Migration script available for existing specs, see `@typespec/migrate` for details

### Added public formatIdentifier function

Added public formatIdentifier function.

### Visibility defaults to read

Default visibility is configurable, but default to 'read'.

## Breaking Changes

### Cadl renamed to Typespec

All core cadl packages moved from the `@cadl-lang` group to the `@typespec` group

| Old Package Name      | New Package Name               |
| --------------------- | ------------------------------ |
| @cadl-lang/compiler   | @typespec/compiler             |
| @cadl-lang/rest       | @typespec/rest, @typespec/http |
| @cadl-lang/migrate    | @typespec/migrate              |
| @cadl-lang/openapi    | @typespec/openapi              |
| @cadl-lang/openapi3   | @typespec/openapi3             |
| @cadl-lang/versioning | @typespec/versioning           |

### `rest` library split into `http` and `rest` libraries

Basic http protocol support is in the `http` library, support for resources and ReST are in the `rest` library. The migration tool will correctly update imports in your spec to match the new
libraries.

### Removed Support for Visual Studio 2019 in Visual Studio IDE extension

You must use a later version of Visual Studio

### Removed `emitters` option in configuration

Use `emit` and `options` instead

---

### Website Src Content Docs Release Notes Release 2023 04 11 (`website/src/content/docs/release-notes/release-2023-04-11.md`)

---
title: April 2023
releaseDate: 2023-04-11
---

:::caution
This release contains **breaking changes**
:::

## New Features

### @typespec/compiler

- Emit diagnostic when ambiguous symbol exists between global and usings
- Add support for referencing metatypes ModelProperty `::type` and Operation `::returnType` and `::parameters`
- Relax constraint on derived type overrides
- Prevent use of augment decorators on instantiated templates.
- Allow projectedNames helpers to work with previous projections
- Add helper `interpolatePath` for emitter to do additional interpolation on config properties
- Api: Update `getTypeName` to omit standard library namespace
- Allow overloads in interfaces to work under projection
- Add pre-projection support
- Provide access to extended interfaces in type graph
- Document member ordering and fix projection rename reordering

### @typespec/openapi3

- Support shared routes
- Update to use new `interpolatePath` logic to resolve the `output-file`

### @typespec/migrate

- Add migrate script for zonedDateTime
- Add migration script for `@header` and `@query` format required

## Bug Fixes

### @typespec/compiler

- Fix: emitter framework will now visit scalar declarations
- Fix: Alias unknown ref crash
- Fix: Empty model expression assignable to array
- Fix: `tsp code uninstall` not finding extension to uninstall
- Fix: Issue where template parameter type check wouldn't work if constraint is exact same type as next validation

### @typespec/rest

- Fix: Issue where `@action("")` was treated the same as `@action`. Now this emits an error.

### @typespec/versioning

- Fix: Issue with using version as a template parameter across different namespaces. Includes a significant change in the versioning library internals.
- Fix:Use pre-projections to fix issues with versioned resources.

### VS Code extension

- Fix: Highlighting of TypeSpec code blocks in markdown.

## Breaking Changes

### @typespec/versioning: Removed deprecated versioning symbols.

- Removed `@versionedDependency` decorator. Use `@useDependency` instead.
- Removed `getRenamedFromVersion`. Use `getRenamedFromVersions` instead.
- Removed `getRenamedFromOldName`. Use `getNameAtVersion` instead.
- Removed `getAddedOn`, `addedAfter`, `getRemovedOn` and `removedOnOrBefore`. Use `existsAtVersion` instead.
- Removed `renamedAfter`. Use `hasDifferentNameAtVersion` instead.

### @typespec/compiler: Removed `zonedDateTime` and replaced with `utcDateTime` and `offsetDateTime`

To disambiguate important time concepts and encourage best practice behavior in representing date-time types we
removed `zonedDateTime` which was being used to represent a time with offset, and replaced it with two new types that are more precisely defined:

- `utcDateTime` which represents a precise instant in time. This type should be used to represent time values given in coordinated universal time (UTC) and unix timestamps. This is the preferred mechanism for capturing dateTime in most service specifications.
- `offsetDateTime` which represents a time with offset. Note that while this time contains an offset from UTC, it does not contain any additional time zone information.

#### Change instances of `zonedDateTime` to `utcDateTime`

##### Old

```typespec
model MyModel {
  createdAt: zonedDateTime;
}
```

#### New

```typespec
model MyModel {
  createdAt: utcDateTime;
}
```

#### Use the (experimental) Migration tool to make this change

The (experimental) migration tool will automatically migrate instances of `zonedDateTime` to `utcDateTime`. To perform all migrations in a TypeSpec or Cadl specification package, execute:

```bash
npx @typespec/migrate
```

If you would like to execute from a different folder or don't have a package.json that indicates compiler package versions, please see command line options:

```bash
npx @typespec/migrate --help
```

### @typespec/http: Removed header and query default format

`@header` and `@query` no longer default the `format` to `csv` and `multi` respectively. A value must now be provided when the type is an array. The migration tool can also be used to make this change.

### @typespec/lint: Removed global state

Rules from another library can no longer be enabled on a LibraryLinter.

---

### Website Src Content Docs Release Notes Release 2023 05 10 (`website/src/content/docs/release-notes/release-2023-05-10.md`)

---
title: May 2023
releaseDate: 2023-05-10
---

:::caution
This release contains **breaking changes**
:::

## New Features

### @typespec/compiler features

- Add `@encode` decorator, with new formats for date and duration encoding support
  - `"rfc3339"`, `"rfc7231'` for `utcDateTime`, `offsetDateTime` types
  - `"unixTimestamp"` support for `utcDateTime` type
  - `"iso8601"` support for `duration` types
  - `"base64"`, `"base64url"` support for `bytes` types
- Allow default values for required model properties and parameters
- `sourceModel` property added to `Model` types
- `sourceOperation` property added to `Operation` types
- `Model` and `Scalar` types added to `TypeSpec.Reflection` namespace

### @typespec/http features

- add `@sharedRoute` decorator
- allow union types within a response status code

### @typespec/openapi3 features

- Enhanced support for shared routes
- Support for union types within a response status code

## Bug Fixes

- General fixes to generated reference documentation for all modules

### @typespec/compiler fixes

- Fix: compiler mismatch error recommendation
- Fix: Interface with templated operation causing crash if defined after use
- Fix: Issue with templated operations in templated interface would get cached only by keying on the operation template args.
- Fix: `missing-index` diagnostic showing at the wrong location
- Fix: `--emit` pointing to emitter js entrypoint resolve correct options
- Fix: `scalar` template parameter name conflict with each other

### @typespec/migrate fixes

- Fix: incorrect resolution of tsp version
- Fix: always loading current version of compiler

### @typespec/openapi3 fixes

- Fix openapi3 emitter to mark request body required
- Fix issue where shared request bodies did not emit correctly.

### @typespec/rest

- Add validation to ensure that @action or @collectionAction operations have a specified name when used with `@sharedRoute`

### @typespec/versioning

- Fix: Crash during validation when using certain templated models from versioned library
- Added validation preventing version enums from having duplicate values.
- Fix issue where "is" dependencies were not detected.
- Raise error if versioned spec specifies a single service version.

## Breaking Changes

### `@typespec/compiler`: `isTemplateDeclaration` will only return true for the original declaration and not partially instantiated templates

If library or emitter code needs to detect a partially instantiated template, the code will need to check `isTemplateInstance` _and_ `isTemplateDeclaration` properties are false.

## Deprecations

### `@typespec/compiler`: Use `@encode` instead of `@format` for encoding scalars and properties of type `bytes`

The new `@encode` decorator should be used whenever the serialized type on the wire differs from the analogous TypeSpec type

#### Old deprecated usage of `@format` decorator

```typespec
model Foo {
  @format("base64url")
  bar: bytes;
}
```

#### New usage of `@encode` decorator

```typespec
model Foo {
  @encode("base64url")
  bar: bytes;
}
```

### http: Use `@sharedRoute` instead of the `shared` property of `@route` options

The new `@sharedRoute` decorator replaces `@route` options for identifying operations that share a route

#### Old deprecated usage of `@route` decorator `shared` option

```typespec
@route(
  "/doStuff",
  {
    shared: true,
  }
)
op doIntStuff(input: int32): int32;

@route(
  "/doStuff",
  {
    shared: true,
  }
)
op doStringStuff(input: string): string;
```

#### New usage of `@sharedRoute` decorator

```typespec
@sharedRoute
@route("/doStuff")
op doIntStuff(input: int32): int32;

@sharedRoute
@route("/doStuff")
op doStringStuff(input: string): string;
```

---

### Website Src Content Docs Release Notes Release 2023 06 06 (`website/src/content/docs/release-notes/release-2023-06-06.md`)

---
title: June 2023
releaseDate: 2023-06-06
---

:::caution
This release contains **breaking changes**
:::

## New Features

- Json Schema Emitter
- New decimal types
- Support for using doc comments instead of the @doc decorator
- New `valueof` type constraint modifier for type literals
- Lazy evaluation of emitter configuration
- Signature Help for Template Arguments and other IDE improvements

### New Decimal Types

Added support for `decimal` and `decimal128` types

```typespec
model Foo {
  price: decimal;
  shortPrice: decimal128;
}
```

These types represent values stored in decimal format which are often used in financial calculations to avoid rounding errors introduced by binary floating point formats. `decimal` can store values of any size and precision, while `decimal128` corresponds to the 128 bit decimal floating point format described by IEEE 754.

### Support for Doc Comments

Doc comments (`/** */`) will be treated as the documentation for types, unless there is an explicit `@doc` decorator

```typespec
/** This will now be the documentation for model Foo */
model Foo {
  name: string;
}
```

### New `valueof` type constraint modifier to require type literals

Templates and decorators can now constrain arguments to literal types. For example, the following template constraint:

```typespec
model Foo<T extends valueof string> {
  @doc(T)
  name: string;
}
```

would match quoted literal strings, "this", as well as references to enum values. Templates and decorators that require string values should change to using this new formulation.

### Allow lazy evaluation of emitter config

- Validate linter configuration only for linters that are executing. This removes warnings for emitters that are configured but not available in a particular compilation.

### Enable Signature Help for Template Arguments

- Template completion will now have similar help in IDE language server as decorators currently do.

### Show documentation Comments on Aliases in IDE Language Tooling

- Documentation comments will show up in the IDE, just as documentation comments for other library types.

### Ensure a dev release for all packages

- Packages with no changes will now release with a `-dev.0` version in dev releases.

### Json Schema Emitter

- Core packages now contain a Json Schema emitter `@typespec/json-schema`

## Bug Fixes

-`tspconfig.yaml` should always get resolved relative to the entrypoint.

- `Array` and `Record` doc comments are treated as developer documentation.

- Fixed formatting of comment between decorator and `op` statement.

- Decorators on operations may reference the same operation, or may reference an operation that references this operation.

```typespec
interface FooOperations {
  @nextPageOperation(getNextPage) // allowed
  getNextPage(pageLink: url): Page<Foo>;
}
```

- Fix validation for `unixTimeStamp`.

- Fix diagnostic for `intrinsic type expected` to not assume `string` as the required type.

- Fix error message for `@encode` errors.

- Fix error handling when template is missing or invalid in `tsp init`.

- Emitter framework: uppercase type argument type names when constructing a declaration name from a template instantiation.

- Add reference documentation for missing decorators.

- Remove dependency on `node-fetch`.

- Remove inaccurate output directory message from compilation success.

- Allow template resolution over http redirects for `tsp init` templates.

- Improve signature help for an unterminated argument list.

## New Deprecations

- Templates that use decorators with the `valueof` constraint will receive a warning if their input types are not similarly constrained.

```typespec
model Foo<T extends string> {
  @doc(T) // valueof constraint here will cause a warning
  id: uuid;
}
```

should be changed to apply the valueof constraint to their parameters that are passed to such decorators:

```typespec
model Foo<T extends valueof string> {
  @doc(T) // no warning
  id: uuid;
}
```

- The `object` type is deprecated. Templates and decorators should use TypeSpec.Reflection.Model to indicate a model contraint. In specs, `{}` designates and empty model, `unknown[]` indicates and empty array, and `Record<unknown>` indicates a keyed type with unknown property types.

## Breaking Changes

- Decorators that require literal type value marshalling MUST change to using the `valueof` keyword.

```typespec
extern dec myDecorator(target: Type, name: string);
```

Must be changed to use the valueof decorator

```typespec
extern dec myDecorator(target: Type, name: valueof string);
```

- Arrays are no longer assignable to an empty model (or object)

- Remove `@format(\"url\") from url scalar. OpenAPI emitters will still emit the appropriate format, emitters should rely on the scalar type to determine how to process the url type, not the format string.

---

### Website Src Content Docs Release Notes Release 2023 07 11 (`website/src/content/docs/release-notes/release-2023-07-11.md`)

---
title: July 2023
releaseDate: 2023-07-11
---

:::caution
This release contains **breaking changes**
:::

## New Features

### `@typespec/compiler` and core language

- New built-in linter system. Typespec libraries are able to define linting rules which can be configured in `tspconfig.yaml`. See documentation for [configuring a linter](https://typespec.io/docs/handbook/configuration#linter---configuring-linters) and [writing a linter](https://typespec.io/docs/extending-typespec/linters)
- Allow decorators, directives and doc comments to be specified in any order
- Format doc comments above decorators and directives
- Improve formatting for properties with comments and decorators
- Support for new Unicode 15.0 identifier characters

### Emitter framework

- Add `writeOutput` to TypeEmitter for additional customization in writing generated files
- Add `meta` property to source files and declarations to store arbitrary metadata
- Add support for emitting enum member references
- Add new `TypeEmitter` methods for scalar instantiation

### `@typespec/http` library

- Add documentation on automatic header name resolution from property name for `@header` decorator

### `@typespec/json-schema` emitter

- Support `@extension` for adding arbitrary vendor extensions into the output
- Add support for `Record<T>`
- Support templates instantiated with intrinsic types and type expressions
- Export emitter and related types from the npm package
- By default, types that are not marked with `@jsonSchema` or are within a namespace with `@jsonSchema` are bundled into the schemas that reference them. Set the `emitAllRefs` option to true to get the previous behavior of emitting all types referenced as JSON Schema

### `@typespec/openapi3` emitter

- Omit `x-typespec-name` extension by default from openapi3 output. A new configuration and command line option `include-x-typespec-name: \"inline-only\" | \"never\"` has been added to get previous behavior

### `@typespec/rest` library

- Add `isListOperation` function migrated from `@typespec/compiler`

## Bug Fixes

### `@typespec/compiler` and core language bug fixes

- Add support for `UTF-8 with bom` for other files loaded by TypeSpec compiler. `.tsp` files already had support, this make it more available for any library/emitter using the compiler api to load a file.
- Fix signature help after comment with no closing parenthesis or angle bracket
- Doc comment `/** */` should override base type doc in `model is` or `op is`
- Formatter incorrectly formatting `::` to `.`
- Fix formatting issue with comment between decorator and scalar or interface
- Fix stack overflow when a circular reference with `op is` exists inside an interface.
- Clean up handling of non-standard entrypoints in language server
- Fix stack overflow when referencing decorator target in checker and projections

### `@typespec/openapi3` emitter bug fixes

- OpenAPI emitters: treat union namespaces like namespaces for other types

### Emitter framework bug fixes

- Fix that some context methods were not being passed the expected parameters
- Fix that context was set incorrectly for some `TypeEmitter` methods, and add missing context methods for model properties, enum members, and union variants

### `@typespec/json-schema` emitter bug fixes

- Fix a bug that could result in a schema being bundled more than once

## Breaking Changes

### For Specification Authors

- Update tsp init template schema for future extensibility. Older tsp version will fail validation when trying to initialize a project with a new template definition.
- Json Schema Emitter: the namespace has been corrected to TypeSpec.JsonSchema. Update any using statements from `JsonSchema` to `TypeSpec.JsonSchema`, and any references from `JsonSchema.[Type]` to `TypeSpec.JsonSchema.[Type]`.

### For Emitters and Libraries

- Minimum version of TypeScript updated to 5.0. TypeSpec is using new features available in TypeScript 5.0 which result in a definition file not parsable by older version. Note that this only affect compiling TypeScript code and is not breaking any JS or TypeSpec code. [See more information on typescript 5.0](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/)
- Emitter Framework: Add support for templates instantiated with types without declared names. In such cases, `TypeEmitter`'s declarationName method may return `undefined`, and so the various `*Instantiation` methods might be called with an undefined name, and `AssetEmitter`'s `emitDeclarationName` method might return undefined.
- Make internal `@resourceTypeForKeyParam` decorator in `@typespec/rest` library private

## Deprecations

- `@list` decorator from TypeSpec core is deprecated. Use `@listsResource` from `@typespec/http` instead
- `isListOperation` function from TypeSpec core is deprecated. Use `isListOperation` from `@typespec/http` instead
- `getListOperationType` from TypeSpec core is deprecated
- `@typespec/linter` Package is deprecated in favor of built-in linter system

---

### Website Src Content Docs Release Notes Release 2023 08 08 (`website/src/content/docs/release-notes/release-2023-08-08.md`)

---
title: August 2023
releaseDate: 2023-08-08
---

:::caution
This release contains **breaking changes**
:::

## New Features

### `@typespec/compiler` New Features

- Allow unnamed variants in named unions
- Add `#deprecated` directive to replace `@deprecated` decorator, allowing deprecation any language element
- Add a new util `resolveCompilerOptions` to resolve compiler options from a given entrypoint. This will resolve the options from the tspconfig.yaml in the same way the cli would.
- Improvements to compiler watch mode. Files loaded in previous compilation will be watched for changes.
- Allow library dependency versions to be specified in init templates using the form `{ name: \"the-lib\", version: \"1.0.0\" }`
- Update init template version compare to be greaterThanAndEqual instead of greaterThan.

### `@typespec/http` New Features

- Update model, operation and template docs for OpenAPI developers
- Add collection format support for query and header properties: simple, form, ssv, tsv, pipes

### `@typespec/openapi` and `@typespec/openapi3` New Features

- Add new `@info` decorator providing the ability to specify the additional fields from openapi info object.
- Support collection format support for query and header properties: simple, form, ssv, tsv, pipes
- Change datetimes encoded with `rfc7231` to produce format `http-date` instead of `date-time-rfc7231` to be inline with [Openapi format registry](https://spec.openapis.org/registry/format/)

## Bug Fixes

### `@typespec/compiler` Bug Fixes

- Fix: Compiler version mismatch error would fire incorrectly
- Fix some issues with not reporting deprecation on template constraints
- Fix issue where using augment decorators on spread model properties, enum members or operations extended from parent interface would have no effect.
- Fix issue where using augment decorator on operation parameters applied to source operation parameter as well.
- Fix `warn-as-error` configuration in `tspconfig.yaml` was ignored
- Emit diagnostic for an unresolved metatype property reference
- Fix crash when `using` argument is not a namespace

### `@typespec/openapi3` Bug Fixes

- Fix: Emit clear diagnostics for empty unions and enum types
- Fix: Apply `@minItems` and `@maxItems` decorators on model array

### `@typespec/jsonschema`

- Fix: Crash when using interfaces inside a `@jsonSchema` namespace

## Breaking Changes

### `@typespec/compiler` Breaking Changes

- Emitter Framework: `sourceFile` method can return a `Promise`. This allows running async processes when generating the file content, such as a formatter. This results in a potential breaking change if calling `emitSourceFile` where you'll have to add `await` before.
- The helper function `formatTypeSpec` is now async. Formatter was updated to use prettier 3.0.

---

### Website Src Content Docs Release Notes Release 2023 09 12 (`website/src/content/docs/release-notes/release-2023-09-12.md`)

---
title: September 2023
releaseDate: 2023-09-12
---

:::caution
This release contains **breaking changes**
:::

## New Features

### `@typespec/compiler` New Features

- Allow library authors to precisely define the visibility of operation templates with new decorators `@parameterVisibility` and `@returnTypeVisibility`, paired with corresponding accessor methods `getParameterVisibility` and `getReturnTypeVisibility`.
- Add coloring for documentation comments in Visual Studio and Visual Studio Code language extensions.
- Change yaml parser from `js-yaml` to `yaml`, enabling more precise validation and error reporting in `tspconfig.yaml`
- Added validation to ensure that properties of a derived model (using `extends`) are compatible with the base model indexer.
- Export `CompilerOptions` TypeScript type.
- Report library information when library code crashes during `$onValidate` execution.
- Diagnostics reported on a node with an `id` property will highlight the id instead of the entire node. For example, if a diagnostic is reported on a `model` type, the model name will be highlighted, instead of the entire model definition.

### `@typespec/http` New Features

- Add new helper method `resolveRequestVisibility` which incorporates settings from new core decorators `@parameterVisibility` and `@returnTypeVisibility`. This replaces the deprecated `getRequestVisibility` helper.
- Add new helper method `getDefaultVisibilityForVerb` which returns the default visibility for Http verbs.
- Add validation step to issue a warning when an `operation is` statement does not include route information from the original operation container (`interface` or `namespace`). This helps to prevent unexpected route changes when using operation references.
- Add validation to prevent runtime errors when `OAuth2Auth` is given invalid `OAuth2Flow` arguments.

### `@typespec/json-schema` New Features

- Support decimal scalar types.

### `@typespec/openapi3` New Features

- Allow library authors to override default Http verb visibility in operation declarations.

### `@typespec/protobuf` New features

- Support `omit-unreachable-types` option.
- Automatically convert empty operation parameters into a reference to `google.protobuf.Empty` instead of synthesizing an empty model.

### `typespec-vscode` New features

- Add color definition for `@param` tag in documentation comments

## Bug Fixes

### `@typespec/compiler` Bug Fixes

- Fix issue where specifying a directory using the `--config` command line option would search the parent folder hierarchy looking for `tspconfig.yaml`.
- Fix Stack overflow when a model property references itself.
- Fix compiler crash when using the alias of a namespace that has decorators.
- Fix compiler freeze when an invalid token appears between doc comment and type.
- Fix compiler crash when relating recursive types.
- Fix typo in format error diagnostic.

### `@typespec/openapi3` Bug Fixes

- Fixed issue where parameters marked with visibility \"create\" did not appear in a `PATCH` request body.
- Fixed incorrect usage of `exclusiveMinimum` and `exclusiveMaximum` boolean properties.
- Use `anyOf` instead of `oneOf` for operations with shared routes and different request or response bodies.
- Fix handling of `Record<T>` in `model is` and `model extends` statements.

### `@typespec/versioning` Bug Fixes

- Fixed validation in `@typeChangedFrom` for incorrect versioned references.

## Deprecations

### `@typespec/compiler` Deprecations

- The `@deprecated` decorator has been marked as deprecated. Use `#deprecated` directive instead.

### `@typespec/http` Deprecations

- The `getRequestVisibility` helper function is now deprecated. Use `resolveRequestVisibility` or `getDefaultVisibilityForVerb` instead.

## Breaking Changes

### `@typespec/compiler` Breaking Changes

- A semicolon is now required at the end of augment decorator statements. The formatter was already inserting the semicolon, if omitted. For example:

  ```tsp
  @@doc(MyType.myProperty, "Documentation for myProperty");
  ```

---

### Website Src Content Docs Release Notes Release 2023 10 11 (`website/src/content/docs/release-notes/release-2023-10-11.md`)

---
title: October 2023
releaseDate: 2023-10-11
---

:::caution
This release contains **breaking changes**
:::

## New Features

### `@typespec/compiler` New Features

- The `never` type is now assignable to all types.
- Allow constraint decorators (e.g. `@minValue`, `@maxValue`, `@maxLength`, etc.) to be applied to nullable types.
- Add support for `@returns` and `@errors` doc comment tags.
  - `@returns`(or `@returnsDoc` decorator) can be used to describe the success return types of an operation.
  - `@errors`(or `@errorsDoc` decorator) can be used to describe the error return types of an operation.
- Skip emit of `deprecated` diagnostic for a type reference that is used in a deprecated declaration statement.
- Improve website performance by removing `decorators` export and importing decorators individually.

### `@typespec/http` New Features

- Add support for `@returns` and `@errors` doc comment tags.
- Add support for status code ranges for http responses. **Change to API** Http responses can now also return a `HttpStatusCodeRange` object for their status codes.
- Emit error diagnostic when multiple properties on a response model have the `@statusCode` decorator.

### `@typespec/json-schema` New Features

- Disable folding of serialized yaml if line is above 80 characters.

### `@typespec/openapi` New Features

- Remove `@typespec/rest` as a `peerDependency`.
- Support Http Status Code ranges.
- **Breaking Change** Changed namespace from `OpenAPI` to `TypeSpec.OpenAPI`.

### `@typespec/openapi3` New Features

- Remove `@typespec/rest` as a `peerDependency`.
- Add support for constraints on union types.
- Add support for `@returns` and `@errors` doc comment tags.
- Add support for http status code ranges.

### `@typespec/protobuf` New features

- Added support for emitting documentation comments in protobuf specifications.

### `@typespec/rest` New features

- Remove peer dependency on `@typespec/http` library.

## Bug Fixes

### `@typespec/compiler` Bug Fixes

- Fix: Correct handling of hyphens in doc comments.
- Fix: Colorization of line comments extending into the next line.
- Fix: Crash when using parentheses in directives.
- Fix: Allow assigning negative and 0 values to `float64` types.
- Fix: Return non-zero format code when tsp formatting fails.
- Fix: Correct formatting of anonymous unions to exclude leading ':' character.
- Fix: Unions and Enum members are now formatted following the same rules as model properties. An extra line will be added between members if the member is annotated with a decorator, directive or doc comment.
- Fix: Correct formatting of comments between a directive or doc and its node.
- Fix: `tsp init` was not creating the `tspconfig.yaml` file for templates that specified it.
- Fix: `tsp init` will create a placeholder `tspconfig.yaml` file for templates that don't specify an explicit one.
- Fix: `tsp init` was ignoring the `files` specified in an init template.
- Fix: Language Server wasn't loading the `tspconfig.yaml` correctly resulting in some options being dropped, like the linter configuration.
- Fix: Allow `null` to be assigned as a default value.
- Fix: Using `TypeSpec.Xyz` namespace shouldn't require the `TypeSpec Prefix`.

### `@typespec/openapi3` Bug Fixes

- Fix: Correctly generate discriminated union mapping property with multiple visibilities.
- Fix: Crash when assigning a numeric default to a union.
- Fix: Using format `ssv` or `pipes` in `@header` produced an invalid OpenAPI3 schema. It will now change the type to string, ignore the format, and emit a warning diagnostic.
- Fix: Allow using null as a default value.
- Fix: Allow use of `@oneOf` on model properties.
- Fix: Correct representation of CSV format.
- Fix: Remove incorrect `statusCode` field for operations with shared routes.

### `@typespec/rest` Bug Fixes

- Fix: `@key` can now appear on the base model of a resource.

### `@typespec/versioning` Bug Fixes

- Ensure that use of `@renamedFrom` does not result in duplicate properties on a model.

## Breaking Changes

### `@typespec/http` Breaking Changes

- Http responses can now also return a `HttpStatusCodeRange` object for their status codes. Emitters will need to handle the additional status code content when processing status codes.
- Emit error diagnostic when multiple properties on a response model have the `@statusCode` decorator.

### `@typespec/openapi` Breaking Changes

- Changed namespace from `OpenAPI` to `TypeSpec.OpenAPI`.

---

### Website Src Content Docs Release Notes Release 2023 11 07 (`website/src/content/docs/release-notes/release-2023-11-07.md`)

---
title: November 2023
releaseDate: 2023-11-07
---

:::caution
This release contains **breaking changes**
:::

## New Features

### `@typespec/compiler` New Features

- Add new `unixTimestamp32` scalar to standard library.
- Emitter Framework: Add hook for handling circular references.
- Emitter Framework: `TypeEmitter` now supports Tuples.
- Emit error diagnostic if a model spreads itself within its declaration.
- Stop showing empty code frame when diagnostic has no location.

### `@typespec/json-schema` New Features

- Add support for `TupleLiteral`.

### `@typespec/openapi3` New Features

- Support `@summary` on data types which emit the JSON Schema `title` property.

### `@typespec/playground` New features

- Add a format button to the playground command bar.
- Add a notification to the standalone playground when the playground has been saved.
- Add resizable panes for the editor and output.

## Bug Fixes

### `@typespec/compiler` Bug Fixes

- Fix: `@doc` and jsdoc comments disappear from multi-segment or nested namespaces.
- Fix: Using `@overload` could result in incorrect `unassignable` type errors.
- Fix: Referencing a template in an alias might cause augment decorators to not be applied on types referenced in the aliased type.
- Fix: Issues with removing keys from `RekeyableMap`.
- Fix: Properties filtered with `@withVisibility` will have their visibility removed. This prevent visibility from being applied twice and rendering invalid models.

### `@typespec/openapi3` Bug Fixes

- Fix: Stops emitting an error when using `@body _: void` in operation parameters and treat it as no body.
- Fix: Using shared routes would, in some cases, result in a `duplicate-header` error.

## Breaking Changes

### Typescript types breaking change

The `package.json` files for all packages have been changed to use the standard `types` field instead of the legacy `typesVersions` field to specify types for subpath exports. This means that packages consuming TypeSpec must use the `moduleResolution` setting with `node16` or `nodenext` in their `tsconfig.json`.
You might see the following error:

```bash
Cannot find module '@typespec/compiler/testing'. Did you mean to set the 'moduleResolution' option to 'nodenext'
```

This can be resolved by changing the following in `tsconfig.json`:

```diff
-"moduleResolution": "ESNext",
+"moduleResolution": "node16",
```

### Dropped Support for Node version 16

- All TypeSpec packages now specify node 18 as the minimum version. Consuming packages should no longer use node 16 and update the node specification in the `engines` section of their package.json file appropriately.

### `@typespec/playground` Breaking Changes

- Styles must be imported seperately with `import \"@typespec/playground/styles.css\";`.

### `@typespec/versioning` Breaking Changes

- Update targets for `@added`, `@removed`, `@renamedFrom`, `@madeOptional` and `@typeChangedFrom` to more clearly communicate where they can be used. Specs that applied these decorators to types that could not be versioned (like `namespace`) will now receive an error diagnostic.

---

### Website Src Content Docs Release Notes Release 2023 12 06 (`website/src/content/docs/release-notes/release-2023-12-06.md`)

---
title: December 2023
releaseDate: 2023-12-06
---

:::caution
This release contains **breaking changes**
:::

## New Features

### `@typespec/compiler` New Features

- **New Language Feature** Added string template literal in typespec. Single and multi-line strings can be interpolated with `${` and `}`. Example `\\Doc for url ${url} is here: ${location}\\`
- [Emitter Framework]: `emitTypeReference` function takes an optional reference context that can be used to patch the context for the target.
- [Emitter Framework]: Added `absolute-path` as a known format for emitter options which will validate the value passed by the user resolve to an absolute path.
- [Emitter Framework]: Allow scalar and enum declarations to provide a reference context.
- [Emitter Framework]: Allow passing a custom context when calling `emitType`.
- Linter rules can now supply a full url to documentation.
- Upgrade formatter to `prettier` version 3.1.

### `@typespec/http` New Features

- Add diagnostic when a namespace exists with routes, but no namespace is marked with `@service`.

### `@typespec/json-schema` New Features

- Add support for simple literal default on model properties.
- Add support for `StringTemplate` literals.

### `@typespec/openapi3` New Features

- Now emits all properties of unreferenced schemas.
- Treat union variants as Discriminator.
- Emitter will now emit all properties of unreferenced schemas.

### `@typespec/playground` New features

- Add a format button to the playground command bar.
- Add a notification to the standalone playground when the playground has been saved.
- Enable changing the theme.
- Add resizable panes for the editor and output
- Add ability to pass a custom footer and use `Footer` and `FooterItem` component to build your own.
- Add `noopener noreferrer` to footer external link
- Move errors and warnings to a dedicated expandable banner at the bottom of the playground.
- **BREAKING CHANGE** Styles must be imported seperately with `import \"@typespec/playground/styles.css\";`
- Allow standalone playground to show a loading fallback.
- Upgrade swagger-ui component.

### `@typespec/rest` New Features

- Fix issue with `ResourceCreateModel` template collecting \"update\" properties instead of \"create\" properties.

## Bug Fixes

### `@typespec/compiler` Bug Fixes

- [Formatter]: Fix: Preserve parentheses in `valueof` expressions inside a union or array (e.g. `(value of strring) | Model`).
- Fix: Union variants are now assigned to the parent union.

### `@typespec/json-schema` Bug Fixes

- Fix: Enum with a value of `0` would have resulted in `type` of `string` and `number`.
- Fix: Scalar constraints combine with base scalar constraints.
- Fix `@maxValueExclusive` setting `minimumExclusive` instead of `maximumExclusive`

### `@typespec/openapi3` Bug Fixes

- Fix: Report diagnostic instead of throwing errors in the case of duplicate ids or unknown scalar.
- FIX: Handle `bytes` as a multipart part type correctly and produce `type: string, format: binary`

### `@typespec/playground` Bug Fixes

- Configure the program viewer to respect the color theme",

### `@typespec/versioning` Bug Fixes

- Fix crash in versioning library`.

## Breaking Changes

- **New Language Feature** string interpolation to strings in TypeSpec. Strings that use the sequence `${` are now expected to start a reference to an interpolated value. Strings that contain `${` and are not meant for interpolation must now be escaped with a `\`, like this: `\${`.

### Semantic Changes in OpenApi3 Output

- Previously, unreferenced `Model` types (types not used in any operation) were emitted using `read` visibility, meaning that properties that had only `create` or `update` visibility would not be included in the corresponding schema in the `@typespec/openapi3` emitter. In this release, all properties of unreferenced Model types will appear in the output.
- Previously, `bytes` types that appeared in a `multipart/form-data` request or response would be marked as a base64 encoded string. In this release, `multipart/form-data` `bytes` types appearing in parts with an `object` type will be treated as a base64-encoded string, while those in non-model parts will appear as raw binary data.

---

### Website Src Content Docs Release Notes Release 2024 01 23 (`website/src/content/docs/release-notes/release-2024-01-23.md`)

---
title: January 2024
releaseDate: 2024-01-23
---

:::caution
This release contains **breaking changes**
:::

## New Features

### `@typespec/compiler` New Features

- **New Language Feature** Added support for named template arguments. Typespec template arguments can now be instantiated both positionally and by name. See [this issue](https://github.com/microsoft/typespec/issues/2340) for details.
  - All TypeSpec libraries normalized Template parameter names in anticipation of this change.
- Renamed template parameters in preparation for named template argument instantiation.
- Added new `--template` option to `tsp init` command line action which lets user specify which template to choose from in the template list.
- Added a new init template for creating a new TypeSpec emitter.
- Added a new init template for creating a new TypeSpec library.
- **New Language Feature** Added the ability to use another template parameter as a constraint, e.g. `model Foo<A, B extends A>`.
- Added `@encodedName` decorator and `getEncodedName` accessor.
- Added support for bytes encode to the general encode type.
- Library declaration: Enabled declaration of State symbols in the library declaration, providing a central place to define state symbols used in your libraries.
- Added a new helper function to change casing to the init templates.

### `@typespec/bundler` New Features

- Support for the `types` entry under `exports` in package definitions (instead of the legacy `typesVersions`).
  - All TypeSpec libraries are now using this definition style.
- Add a new cli for `typespec-bundler`.
- Expose a bundle manifest with relative importmap, package name, and version.

### `@typespec/openapi3` New Features

- Added support for `@encodedName` decorator.

### `@typespec/playground` New features

- Added a format button to the playground command bar.
- Added a notification to the standalone playground when the playground has been saved.
- Added resizable panes for the editor and output.
- Added the ability to pass a custom footer and use `Footer` and `FooterItem` component to build your own.
- Added the ability to configure the playground via `createBrowserHost` if library loading should use system `importmap` or the es-module-shim library with `importmap-shim`. This was added due to the lack of support for external source map in browsers.
- Provided the ability to configure bundling local libraries with the playground or manage the `importmap` yourself with `skipBundleLibraries` option.
- Moved errors and warnings to a dedicated expandable banner at the bottom of the playground.
- Removed `githubIssueUrl` link and replaced with a `onFileBug` callback.
- Allowed standalone playground to show a loading fallback.

## Bug Fixes

### `@typespec/compiler` Bug Fixes

- Fix: Improved performance of the language server, impacting performance of syntax highlighting and other IDE features.
- Fix: Enabled compiler file resolution for long path names (256+ characters) on windows.
- Fix: Turned off warning when `tsp init` is used with a template that does not specify `compilerVersion`.

### `@typespec/http` Bug Fixes

- Fix: Ensured `@path` custom name is respected.
- Fix: Allowed correct path generation when path parameter is not alpha numeric(Either with a different name provided in `@path` or if the property name is not an identifier)

### `@typespec/playground` Bug Fixes

- Fix: Configured the program viewer to respect the color theme.
- Fix: Provided css exports to `styles.css` in addition to `style.css`. Both are now available for backward compatibility but `styles.css` is the recommended name.

### `@typespec/rest` Bug Fixes

- Fix: Corrected handling of custom @path name in the building of the route.

### `@typespec/versioning` Bug Fixes

## Deprecations

### `@typespec-compiler` Deprecations

- Library declaration: Deprecated linter property on `$lib` in favor of a new `$linter` variable that can be exported. This was done to discourage circular references caused by referencing linter rules in `$lib`.

## Breaking Changes

### Node Version Requirement

- TypeSpec dropped support for node version 16, as this version of node is no longer generally supported. Minimum node version is 18.

### `typespec-playground` Breaking Changes

- **BREAKING CHANGE** Styles must be imported seperately with `import \"@typespec/playground/styles.css\";`.

---

### Website Src Content Docs Release Notes Release 2024 02 06 (`website/src/content/docs/release-notes/release-2024-02-06.md`)

---
title: February 2024
releaseDate: 2024-02-06
---

## Release of VSCode and Visual Studio extensions

- [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=typespec.typespec-vscode)
- [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=typespec.typespecvs)

## New Features

### `@typespec/compiler` New Features

- Added an optional validation message to the @pattern decorator.
- Emitter framework: `ObjectBuilder` will keep track when built using a `Placeholder` allowing data to be carried over when chaining `ObjectBuilder`

### `@typespec/openapi3` New Features

- Added support for `@encodedName` decorator.

## Bug Fixes

### `@typespec/compiler` Bug Fixes

- Template instantiated with ErrorType will get the arg changed to unknown
- Fix: Error out when using properties in array model

### `@typespec/http` Bug Fixes

- Fix: OpenIDConnect types not exposed on the TypeScript types

### `@typespec/openapi3` Bug Fixes

- Fix issues with `nullable` properties used in a cycle being wrapped in `allOf` when not needed
- Fix circular reference would not always inline array properties
- Add support for OpenIdConnect auth scheme

---

### Website Src Content Docs Release Notes Release 2024 03 05 (`website/src/content/docs/release-notes/release-2024-03-05.md`)

---
title: March 2024
releaseDate: 2024-03-05
---

:::caution
This release contains breaking changes and deprecations
:::

## Breaking Changes

### `@typespec/compiler`

- [#2920](https://github.com/microsoft/typespec/pull/2920) Intersecting `Record<T>` with incompatible properties will now emit an error

### `@typespec/prettier-plugin-typespec`

- [#2956](https://github.com/microsoft/typespec/pull/2956) Drop support for prettier 2.0

## Deprecations

### `@typespec/compiler`

- [#2919](https://github.com/microsoft/typespec/pull/2919) [API] Create a new export `@typespec/compiler/utils` exports. Deprecate export from `@typespec/compiler` of utils like `DuplicateTracker`, `Queue`, `createTwoKeyMap`, etc.
- [#2902](https://github.com/microsoft/typespec/pull/2902) Deprecate `@service` version property. If wanting to describe a service versioning you can use the `@typespec/versioning` library. If wanting to describe the project version you can use the package.json version. For OpenAPI generation. the `@OpenAPI.info` nows decorator allows providing the document version.

## Features

### `@typespec/compiler`

- [#2888](https://github.com/microsoft/typespec/pull/2888) Add support for codefixes
- [#2920](https://github.com/microsoft/typespec/pull/2920) Add support for `...Record<T>` to define the type of remaining properties
- [#2968](https://github.com/microsoft/typespec/pull/2968) Any subtype of an error(marked with `@error`) is now an error.

### `@typespec/http`

- [#2901](https://github.com/microsoft/typespec/pull/2901) Add ability to specify authentication and different scopes per operation
- [#2958](https://github.com/microsoft/typespec/pull/2958) Validate that only one `@useAuth` decorator is applied to a type.

### `@typespec/openapi`

- [#2902](https://github.com/microsoft/typespec/pull/2902) Add support for all properties of openapi `info` object on the `@info` decorator

### `@typespec/openapi3`

- [#2902](https://github.com/microsoft/typespec/pull/2902) Add support for all properties of openapi `info` object on the `@info` decorator
- [#2950](https://github.com/microsoft/typespec/pull/2950) Add `getOpenAPI3` function that takes a TypeSpec program and returns the emitted OpenAPI as an object. Useful for other emitters and tools that want to work with emitted OpenAPI directly without writing it to disk.
- [#2933](https://github.com/microsoft/typespec/pull/2933) Add a new option `safeint-strategy` that can be set to `double-int` to emit `type: integer, format: double-int` instead of `type: integer, format: int64` when using the `safeint` scalar.

### `@typespec/playground`

- [#2936](https://github.com/microsoft/typespec/pull/2936) Autocomplete installed libraries in `import` statements

## Bug Fixes

### `@typespec/compiler`

- [#2932](https://github.com/microsoft/typespec/pull/2932) Report error when having a circular template constraint e.g. `model Example<T extends T>`
- [#2955](https://github.com/microsoft/typespec/pull/2955) [Formatter] Formatting file with only comments would reorder the first line.
- [#2934](https://github.com/microsoft/typespec/pull/2934) [IDE] Fix issue when deleting an open file outside the IDE that would crash the language server
- [#2959](https://github.com/microsoft/typespec/pull/2959) Decorators that have missing arguments will not run. This is inline with passing invalid argument to a decorator that would prevent it from running.
- [#2976](https://github.com/microsoft/typespec/pull/2976) [IDE] Fix type documentation shown twice when hovering symbols or in completion details.
- [#2929](https://github.com/microsoft/typespec/pull/2929) [API] Add `Scalar` to TS `TemplatedType` type
- [#2978](https://github.com/microsoft/typespec/pull/2978) [IDE] Go to imports
- [#2936](https://github.com/microsoft/typespec/pull/2936) [IDE] Autocompleting file or folder with non alpha numeric character completes correctly
- [#2936](https://github.com/microsoft/typespec/pull/2936) [IDE] Fix crashing when trying to autocomplete an invalid folder
- [#2951](https://github.com/microsoft/typespec/pull/2951) Wrap string in quotes in errors
- [#2886](https://github.com/microsoft/typespec/pull/2886) Fix: `tsp compile --watch` was missing coloring and error previews

### `@typespec/http`

- [#2948](https://github.com/microsoft/typespec/pull/2948) Fix don't emit shared route error when verb don't match

### `@typespec/json-schema`

- [#2977](https://github.com/microsoft/typespec/pull/2977) Respect compiler `noEmit` flag

---

### Website Src Content Docs Release Notes Typespec 0 55 (`website/src/content/docs/release-notes/typespec-0-55.md`)

---
slug: release-notes/typespec-0-55
title: 0.55 - April 2024
releaseDate: 2024-04-02
version: "0.55"
---

:::caution
This release contains deprecations
:::

## Deprecations

### @typespec/compiler

- [#2910](https://github.com/microsoft/typespec/pull/2910) Deprecate `@projectedName` decorator. `@encodedName` should be used instead.

  Example:

  ```diff
  -@projectedName("json", "exp")
  +@encodedName("application/json", "exp")
  ```

- [#3094](https://github.com/microsoft/typespec/pull/3094) Deprecate `@knownValues` decorator. Use a named union of string literal with a string variant to achieve the same result without a decorator

  Example:

  ```diff
  -enum FooKV { a, b, c}
  -@knownValues(FooKV)
  -scalar foo extends string;
  +union Foo { "a", "b", "c", string }
  ```

## Features

### @typespec/compiler

- [#2992](https://github.com/microsoft/typespec/pull/2992) Enable the use of `@encode` for model properties that have a union type. This supports cases like `@encode("rfc3339") prop: utcDateTime | null`

### @typespec/versioning

- [#3053](https://github.com/microsoft/typespec/pull/3053) Add support for versioning of scalars(Added, removed, renamed)

## Bug Fixes

### @typespec/compiler

- [#3018](https://github.com/microsoft/typespec/pull/3018) Grammar: Fix comments in template params not tokenized
- [#3052](https://github.com/microsoft/typespec/pull/3052) Fix: Union template declaration were incorrectly being finished in projection
- [#2983](https://github.com/microsoft/typespec/pull/2983) Warnings converted to error with `warn-as-error` do not prevent compilation from moving to the next stage like regular warnings
- [#3041](https://github.com/microsoft/typespec/pull/3041) Improve reliability of application of codefixes in IDE, often it would not do anything
- [#3069](https://github.com/microsoft/typespec/pull/3069) TmLanguage: Fix tokenization of escaped identifiers, enums and unions

### @typespec/openapi3

- [#3077](https://github.com/microsoft/typespec/pull/3077) Do not crash if using an unsupported intrinsic type
- [#2967](https://github.com/microsoft/typespec/pull/2967) Fix crash: emit `{nullable: true}` when trying to emit `null` in openapi3
- [#3013](https://github.com/microsoft/typespec/pull/3013) Fix: OpenAPI3 not marking part of bytes or something else as `format: binary`
- [#3090](https://github.com/microsoft/typespec/pull/3090) Fix: Literal unions with the same variants keep adding duplicate entries
- [#3049](https://github.com/microsoft/typespec/pull/3049) Fix visibility naming conflict when a model used with `extends` was used in different visibility.

### @typespec/eslint-config-typespec

- [#2122](https://github.com/microsoft/typespec/pull/2122) Ignore `generated-defs` folder

---

### Website Src Content Docs Release Notes Typespec 0 56 (`website/src/content/docs/release-notes/typespec-0-56.md`)

---
slug: release-notes/typespec-0-56
title: 0.56 - May 2024
releaseDate: 2024-05-07
version: "0.56"
---

:::caution
This release contains breaking changes
:::

## Breaking Changes

### @typespec/http

- [#2945](https://github.com/microsoft/typespec/pull/2945) Empty model after removing metadata and applying visibility always results in "void"
  This means the following case have changed from returning `{}` to no body

  ```tsp
  op b1(): {};
  op b2(): {
    @visibility("none") prop: string;
  };
  op b3(): {
    @added(Versions.v2) prop: string;
  };
  ```

  Workaround: Use explicit `@body`

  ```tsp
  op b1(): {
    @body _: {};
  };
  op b2(): {
    @body _: {
      @visibility("none") prop: string;
    };
  };
  op b3(): {
    @body _: {
      @added(Versions.v2) prop: string;
    };
  };
  ```

- [#2945](https://github.com/microsoft/typespec/pull/2945) Implicit status code always 200 except if response is explicitly `void`

  ```tsp
  op c1(): {
    @header foo: string;
  }; // status code 200 (used to be 204)
  ```

  Solution: Add explicit `@statusCode`

  ```tsp
  op c1(): {
    @header foo: string;
    @statusCode _: 204;
  };
  op c1(): {
    @header foo: string;
    ...NoContent;
  }; // or spread common model
  ```

- [#2945](https://github.com/microsoft/typespec/pull/2945) `@body` means this is the body

  This change makes using `@body` mean this is the exact body and everything underneath will be included, including metadata properties. If metadata properties are present on the body, a warning will be logged.

  ```tsp
  op a1(): {@body _: {@header foo: string, other: string} };
                  ^ warning header in a body, it will not be included as a header.
  ```

  Use `@bodyRoot` if you want to only change where to resolve the body from.

  ```tsp
  op a1(): {
    @bodyRoot _: {
      @header foo: string;
      other: string;
    };
  };
  ```

- [#2945](https://github.com/microsoft/typespec/pull/2945) Properties are not automatically omitted if everything was removed from metadata or visibility

  ```tsp
  op d1(): {
    headers: {
      @header foo: string;
    };
  }; // body will be {headers: {}}
  ```

  Solution: use `@bodyIgnore`

  ```tsp
  op d1(): {
    @bodyIgnore headers: {
      @header foo: string;
    };
  }; // body will be {headers: {}}
  ```

## Features

### @typespec/compiler

- [#3035](https://github.com/microsoft/typespec/pull/3035) `getEncode` returns the fully qualified enum member name if using a custom enum.
- [#3183](https://github.com/microsoft/typespec/pull/3183) Show template parameters when hovering on an operation template
- [#3191](https://github.com/microsoft/typespec/pull/3191) [API] Add new `sourceModels` property to model

### @typespec/rest

- [#2945](https://github.com/microsoft/typespec/pull/2945) Add support for new `@bodyRoot` and `@body` distinction

### @typespec/openapi3

- [#2945](https://github.com/microsoft/typespec/pull/2945) Add support for new `@bodyRoot` and `@body` distinction

### @typespec/html-program-viewer

- [#3191](https://github.com/microsoft/typespec/pull/3191) Add `sourceModels` property to model view

## Bug Fixes

### @typespec/compiler

- [#3170](https://github.com/microsoft/typespec/pull/3170) `--nostdlib` flag will now work by only applying to optional standard library types
- [#3212](https://github.com/microsoft/typespec/pull/3212) Fix: augmenting template model property could result in sending invalid argument to decorator
- [#3188](https://github.com/microsoft/typespec/pull/3188) Fix: Do not crash when trying to access member of aliased expressions
- [#3185](https://github.com/microsoft/typespec/pull/3185) Fix tsp init hanging when done due to unclosed connection
- [#3151](https://github.com/microsoft/typespec/pull/3151) IDE: Fix completion of statement keywords
- [#3287](https://github.com/microsoft/typespec/pull/3287) Templated interface extending another templated interface shouldn't run decorator on their operations
- [#3290](https://github.com/microsoft/typespec/pull/3290) Model with an optional property should not satisfy a constraint with that property required. (`{foo?: string}` cannot be assigned to a constraint of `{foo: string}`)
- [#3163](https://github.com/microsoft/typespec/pull/3163) Fix: Model with spread indexer shouldn't validate explicit properties
- [#3227](https://github.com/microsoft/typespec/pull/3227) Stop running decorators on partially instantiated operations(When interface is instantiated but not the operation)
- [#3180](https://github.com/microsoft/typespec/pull/3180) Fix issue where directives were not parsed to the leaf node in multi-segment Namespace segments.
- [#3243](https://github.com/microsoft/typespec/pull/3243) Fix calling `tsp install` on windows due to recent NodeJS breaking change to fix vulnerability.
- [#3216](https://github.com/microsoft/typespec/pull/3216) Fix compiler crash when using an invalid `is` target in an interface operation template
- [#3246](https://github.com/microsoft/typespec/pull/3246) Internals: Use node built-in `fetch` API that is now stable since node `18.13.0`

### @typespec/http

- [#3196](https://github.com/microsoft/typespec/pull/3196) Fix password flow defining `authorizationUrl` instead of `tokenUrl`
- [#3190](https://github.com/microsoft/typespec/pull/3190) Fix `@path` param mapping when spreading a record in operation parameters
- [#3218](https://github.com/microsoft/typespec/pull/3218) Fix: `@path` property shouldn't be applicableMetadata if the visibility contains `Read`

### @typespec/versioning

- [#3264](https://github.com/microsoft/typespec/pull/3264) Fix crash when `@service` appears inside a versioned namespace

### @typespec/openapi3

- [#3218](https://github.com/microsoft/typespec/pull/3218) Fix: `@path` property should be included in unreachable models

---

### Website Src Content Docs Release Notes Typespec 0 57 (`website/src/content/docs/release-notes/typespec-0-57.md`)

---
slug: release-notes/typespec-0-57
title: 0.57 - June 2024
releaseDate: 2024-06-10
version: "0.57"
---

:::caution
This release contains deprecations and breaking changes
:::

## Values In TypeSpec

Decorators often expect some sort of configuration to be passed as an argument. In version `0.51.0` we introduced the `valueof` keyword to constrain a decorator or template parameter to be a value, however this was limited to string, numeric and boolean values.
When dealing with more complex decorators or free form data, one had to use a model type to represent the data. Unfortunately, this approach was difficult for decorator authors to handle reliably and required somewhat sophisticated validation to avoid some common pitfalls that couldn't be prevented through type system constraints.

In this release we introduce a new concept to TypeSpec: values. This includes new syntax for declaring object and array values, scalar constructors, and `const` declarations.

### Object values

Object values can be declared with the `#{}` syntax.

```tsp
const user = #{ name: "Bob", age: 48, address: #{ city: "London" } };
```

### Array values

Array values can be declared with the `#[]` syntax.

```tsp
const users = #["Bob", "Frank"];
```

### `const`

Const declares a variable that holds a value, and can optionally specify a type.

```tsp
const name = "Bob";
const name: string = "Bob";
```

### Scalar constructors

Scalars can define custom values with scalar value constructors. Scalars which don't extend a base type like `string`, `number` or `boolean` can define a constructor.

```tsp
scalar ipV4 {
  init fromInt(value: int32);
}
const ip: ipV4 = ipV4.fromInt(3232235776);
```

[See values doc for more info](https://typespec.io/docs/language-basics/values)

## Breaking changes

- [#3022](https://github.com/microsoft/typespec/pull/3022) Addition of new `const` keyword means using `const` as a property name or decorator name will result in an error. This can be fixed by wrapping the property in backtick.

```tsp
model Test {
  // error
  const: string;

  // correct
  `const`: string;

}
```

## Deprecations

### @typespec/compiler

- [#3022](https://github.com/microsoft/typespec/pull/3022) Using a tuple type as a value is deprecated. Tuple types in contexts where values are expected must be updated to be array values instead. A codefix is provided to automatically convert tuple types into array values.

```tsp
model Test {
  // Deprecated
  values: string[] = ["a", "b", "c"];

  // Correct
  values: string[] = #["a", "b", "c"];
}
```

- [#3022](https://github.com/microsoft/typespec/pull/3022) Using a model type as a value is deprecated. Model types in contexts where values are expected must be updated to be object values instead. A codefix is provided to automatically convert model types into object values.

```tsp
model Test {
  // Deprecated
  user: {
    name: string;
  } = {
    name: "System";
  };

  // Correct
  user: {
    name: string;
  } = #{ name: "System" };
}
```

- [#3022](https://github.com/microsoft/typespec/pull/3022) Decorator API: Legacy marshalling logic

With the introduction of values, the decorator marshalling behavior has changed in some cases. This behavior is opt-in by setting the `valueMarshalling` package flag to `"new"`, but will be the default behavior in future versions. It is strongly recommended to adopt this new behavior as soon as possible.

Example:

```tsp
extern dec multipleOf(target: numeric | Reflection.ModelProperty, value: valueof numeric);
```

Will now emit a deprecated warning because `value` is of type `valueof string` which would marshall to `Numeric` under the new logic but as `number` previously.

To opt-in you can add the following to your library js/ts files.

```ts
export const $flags = definePackageFlags({
  decoratorArgMarshalling: "new",
});
```

## Features

### @typespec/compiler

- [#3280](https://github.com/microsoft/typespec/pull/3280) Support completion for Model with extended properties

  Example

  ```tsp
  model Device {
    name: string;
    description: string;
  }

  model Phone extends Device {
    ┆
  } | [name]
    | [description]
  ```

- [#3280](https://github.com/microsoft/typespec/pull/3280) Support completion for object values and model expression properties.

  Example

  ```tsp
  model User {
    name: string;
    age: int32;
    address: string;
  }

  const user: User = #{name: "Bob", ┆}
                                    | [age]
                                    | [address]
  ```

- [#3375](https://github.com/microsoft/typespec/pull/3375) Allow `@` to be escaped in doc comment with `\`
- [#3022](https://github.com/microsoft/typespec/pull/3022) Add syntax for declaring values. [See docs](https://typespec.io/docs/language-basics/values).

Object and array values

```tsp
@dummy(#{
  name: "John",
  age: 48,
  address: #{ city: "London" }
  aliases: #["Bob", "Frank"]
})
```

Scalar constructors

```tsp
scalar utcDateTime {
  init fromISO(value: string);
}

model DateRange {
  minDate: utcDateTime = utcDateTime.fromISO("2024-02-15T18:36:03Z");
}
```

- [#3527](https://github.com/microsoft/typespec/pull/3527) Add support for `@prop` doc comment tag to describe model properties
- [#3460](https://github.com/microsoft/typespec/pull/3460) Hide deprecated items from completion list
- [#3462](https://github.com/microsoft/typespec/pull/3462) Linter `all` rulesets is automatically created if not explicitly provided
- [#3533](https://github.com/microsoft/typespec/pull/3533) More logs and traces are added for diagnostic and troubleshooting in TypeSpec language server
- [#3422](https://github.com/microsoft/typespec/pull/3422) Formatter: Indent or dedent multiline strings to the current indentation

### @typespec/http

- [#3342](https://github.com/microsoft/typespec/pull/3342) Add new multipart handling. Using `@multipartBody` with `HttpPart<Type, Options>`. See [multipart docs](https://typespec.io/docs/next/libraries/http/multipart) for more information.

  ```tsp
  op upload(
    @header contentType: "multipart/mixed",
    @multipartBody body: {
      name: HttpPart<string>;
      avatar: HttpPart<bytes>[];
    },
  ): void;
  ```

- [#3462](https://github.com/microsoft/typespec/pull/3462) Use new compiler automatic `all` ruleset instead of explicitly provided one

### @typespec/openapi3

- [#3022](https://github.com/microsoft/typespec/pull/3022) Add support for new object and array values as default values (e.g. `decimals: decimal[] = #[123, 456.7];`)

### @typespec/html-program-viewer

- [#3022](https://github.com/microsoft/typespec/pull/3022) Add support for values

### @typespec/json-schema

- [#3557](https://github.com/microsoft/typespec/pull/3557) Add support for @oneOf decorator.

### typespec-vs

- [#3461](https://github.com/microsoft/typespec/pull/3461) Support Arm64

### typespec-vscode

- [#3533](https://github.com/microsoft/typespec/pull/3533) Enhance logging and trace

1.  Support "Developer: Set Log Level..." command to filter logs in TypeSpec output channel
2.  Add "typespecLanguageServer.trace.server" config for whether and how to send the traces from TypeSpec language server to client. (It still depends on client to decide whether to show these traces based on the configured Log Level.)
3.  More logs and traces are added for diagnostic and troubleshooting

- [#3385](https://github.com/microsoft/typespec/pull/3385) Add 'TypeSpec: Show Output Channel' command in VSCode extension

## Bug Fixes

### @typespec/compiler

- [#3399](https://github.com/microsoft/typespec/pull/3399) Preserve leading whitespace in fenced blocks in doc comments
- [#3522](https://github.com/microsoft/typespec/pull/3522) Fix EINVAL error when running `tsp code install`
- [#3371](https://github.com/microsoft/typespec/pull/3371) Numeric not handling trailing zeros and causing freeze(e.g. `const a = 100.0`)
- [#3451](https://github.com/microsoft/typespec/pull/3451) Emitter framework: fix losing context when referencing circular types
- [#3517](https://github.com/microsoft/typespec/pull/3517) Fix application of `@param` doc tag on operation create with `op is` to override upstream doc
- [#3488](https://github.com/microsoft/typespec/pull/3488) Add `PickProperties` type to dynamically select a subset of a model

### @typespec/http

- [#3022](https://github.com/microsoft/typespec/pull/3022) Update Flow Template to make use of the new array values

### @typespec/versioning

- [#3292](https://github.com/microsoft/typespec/pull/3292) Add `@madeRequired` decorator
- [#3022](https://github.com/microsoft/typespec/pull/3022) Update to support new value types
- [#3409](https://github.com/microsoft/typespec/pull/3409) Using `@removed` on member types and `@added` on containing type could result in errors
- [#3255](https://github.com/microsoft/typespec/pull/3255) If a property were marked with @added on a later version, the logic that said it was originally added on the first version was erroneously removed, resulting in incorrect projections.

### @typespec/rest

- [#3022](https://github.com/microsoft/typespec/pull/3022) Update types to support new values in TypeSpec

### @typespec/openapi3

- [#3342](https://github.com/microsoft/typespec/pull/3342) Add support for new multipart constructs in http library
- [#3574](https://github.com/microsoft/typespec/pull/3574) Emit diagnostic when an invalid type is used as a property instead of crashing.

### @typespec/protobuf

- [#3022](https://github.com/microsoft/typespec/pull/3022) Update to support new value types
- [#3561](https://github.com/microsoft/typespec/pull/3561) Corrected cross-package reference behavior in some buggy cases.
-

### @typespec/json-schema

- [#3398](https://github.com/microsoft/typespec/pull/3398) Fix decorators application for union variants
- [#3022](https://github.com/microsoft/typespec/pull/3022) Update to support new value types
- [#3430](https://github.com/microsoft/typespec/pull/3430) The emitted JSON Schema now doesn't make root schemas for TypeSpec types which do not have the @jsonSchema decorator or are contained in a namespace with that decorator. Instead, such schemas are put into the $defs of any root schema which references them, and are referenced using JSON Pointers.

---

--- METRICS ---
- Files Extracted: 128
- Estimated Token Budget: ~127076 tokens
- Canonical Reference: https://codewiki.google/github.com/microsoft/typespec
