Skip to content

feat(typespec-ts): streaming - #5196

Open
Libba Lawrence (l0lawrence) wants to merge 36 commits into
Azure:mainfrom
l0lawrence:l0lawrence-vigilant-system
Open

Libba Lawrence (l0lawrence) wants to merge 36 commits into
Azure:mainfrom
l0lawrence:l0lawrence-vigilant-system

Conversation

@l0lawrence

@l0lawrence Libba Lawrence (l0lawrence) commented Aug 10, 2026 •

Copy link
Copy Markdown
Member

Adds structured JSONL + SSE streaming code generation to the @azure-tools/typespec-ts modular emitter. A response whose TCGC metadata indicates a structured stream now generates a Promise<AsyncIterable<T>> of deserialized items/events instead of returning the raw binary Uint8Array body. Does not contain reconnection support - depends on createStreamSSE(). Azure Search, the library requesting this feature, does not support reconnection at this point in time.

The sse spec this is based on: https://html.spec.whatwg.org/multipage/server-sent-events.html

What is generated

  • JSONL (JsonlStream<T>) -> Promise<AsyncIterable<T>> that lazily decodes JSON Lines.
  • SSE (SSEStream<T>) -> Promise<AsyncIterable<...>> that dispatches each Server-Sent Event by its event: name (via @azure/core-sse), deserializes the payload, and stops at the terminal event. Full heterogeneous multi-event dispatch and @terminalEvent handling are supported (named terminals keyed on the terminal flag; unnamed data: [DONE] sentinel terminals). Generation is driven by TCGC streamMetadata / sseMetadata.

Issues for the future:
#5660 #5659

Related pr to core for abort signal/canceling stream: Azure/azure-sdk-for-js#40238

…ault

JSONL/SSE stream responses now return Promise<AsyncIterable<T>> of
deserialized items/events instead of the raw binary Uint8Array body.
JsonlStream<T> lazily decodes JSON Lines; SSEStream<T> dispatches each
Server-Sent Event by its event: name (via @azure/core-sse), deserializes
the payload, and stops at the terminal event. Heterogeneous multi-event
dispatch and terminal-event handling are supported.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:typescript Issues for @azure-tools/typespec-ts emitter label Aug 10, 2026
@l0lawrence Libba Lawrence (l0lawrence) changed the title feat(typespec-ts): generate structured JSONL and SSE streaming by default feat(typespec-ts): streaming Aug 10, 2026
Adds the workspace link entries for @typespec/streams, @typespec/sse and
@typespec/events that were added to packages/typespec-ts/package.json for
structured JSONL/SSE streaming. Required so CI's frozen-lockfile install
matches package.json.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • ✅ @azure-tools/typespec-ts
Show changes

@azure-tools/typespec-ts - feature ✏️

Generate structured JSONL and SSE streaming operations as Promise<AsyncIterable<T>> of deserialized items/events instead of raw binary Uint8Array bodies. Connection and modeled HTTP error validation are eager; payload deserialization is lazy. Generate streaming helpers only for supported MIME types and non-paging, non-LRO operations. Deserialize scalar SSE payloads into their declared client types. Dispatch unnamed discriminated SSE model variants by their payload discriminator and yield terminal payloads before stopping.,> ,> SSE uses the published @azure/core-sse createSseStream API. Close the SSE source before delivering a terminal payload, preserving the terminal item and reporting cleanup failures after yielding it.,> ,> JSONL decodes lines incrementally, flushes UTF-8 decoding at EOF, and cancels browser readers on early exit or decoding failures. Per-item deserialization uses existing TCGC serialization metadata.,> ,> Recognize standalone TypeSpec.Streams decorators in the shared test compiler and cover custom streams without incidental SSE imports.

Brings the branch up to date with upstream main so CI can build the PR merge
commit. Resolves the conflict in pnpm-lock.yaml (took upstream and re-added the
@typespec/streams, @typespec/sse and @typespec/events workspace links) and
adapts the structured-streaming deserialize helper to the refactored
getExceptionThrowStatement signature (now [string[], ServiceOperation]).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

📦 Package size report

6 packages changed size, -836 B (-0.0%) packed overall.

Package Packed (base → head) Δ Packed Unpacked (base → head) Δ Unpacked
@azure-tools/typespec-ts 541.44 KB → 549.34 KB +7.90 KB (+1.5%) 🔴 2.60 MB → 2.75 MB +148.34 KB (+5.6%) 🔴
@azure-tools/typespec-azure-portal-core 42.48 KB → 36.26 KB -6.22 KB (-14.6%) 🟢 193.20 KB → 242.62 KB +49.43 KB (+25.6%) 🔴
@azure-tools/azure-http-specs 148.36 KB → 143.52 KB -4.85 KB (-3.3%) 🟢 1.17 MB → 1.20 MB +35.28 KB (+3.0%) 🔴
@azure-tools/typespec-azure-examples 65.86 KB → 62.45 KB -3.40 KB (-5.2%) 🟢 261.37 KB → 308.13 KB +46.76 KB (+17.9%) 🔴
@azure-tools/typespec-autorest 85.05 KB → 87.87 KB +2.82 KB (+3.3%) 🔴 411.46 KB → 424.15 KB +12.69 KB (+3.1%) 🔴
@azure-tools/typespec-azure-core 134.19 KB → 135.62 KB +1.43 KB (+1.1%) 🔴 724.18 KB → 728.92 KB +4.74 KB (+0.7%) 🔴
8 package(s) with no notable change
Package Packed (base → head) Δ Packed Unpacked (base → head) Δ Unpacked
@azure-tools/typespec-client-generator-core 243.03 KB → 243.95 KB +944 B (+0.4%) 1.29 MB → 1.30 MB +4.84 KB (+0.4%)
@azure-tools/typespec-java 13.51 MB → 13.51 MB +254 B (+0.0%) 15.04 MB → 15.04 MB +785 B (+0.0%)
@azure-tools/typespec-go 263.56 KB → 263.76 KB +205 B (+0.1%) 1.35 MB → 1.35 MB +1.82 KB (+0.1%)
@azure-tools/typespec-azure-resource-manager 184.05 KB → 184.13 KB +90 B (+0.0%) 1.11 MB → 1.11 MB +321 B (+0.0%)
@azure-tools/typespec-python 42.22 KB → 42.26 KB +39 B (+0.1%) 164.91 KB → 165.08 KB +175 B (+0.1%)
@azure-tools/typespec-azure-rulesets 5.50 KB → 5.50 KB +10 B (+0.2%) 33.67 KB → 33.69 KB +20 B (+0.1%)
@azure-tools/typespec-autorest-canonical 7.42 KB → 7.42 KB — 26.00 KB → 26.00 KB —
@azure-tools/typespec-metadata 15.91 KB → 15.91 KB — 62.26 KB → 62.26 KB —

Packed = gzipped .tgz published to npm. Unpacked = total extracted size. 🆕 added, 🗑️ removed. Packages from the core/ submodule are not included.
🔴 grew · 🟢 shrank — only changes of at least 512 B and 0.5% are marked.

@pkg-pr-new

pkg-pr-new Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-ts@5196

commit: 61202db

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

Three fixes from a design review of the default JSONL/SSE structured
streaming feature:

1. Split the SSE decoder into a separate sseStreamingHelpers.ts so
   JSONL-only packages no longer import (or need) @azure/core-sse.
   streamingHelpers.ts now contains only JSONL + shared helpers with no
   core-sse dependency. SseStreamingHelpers loads only when the package
   has an SSE operation, matching the @azure/core-sse dependency gate.

2. Only treat a constant SSE event as a terminal sentinel when
   isTerminalEvent is true. A non-terminal constant is a real payload
   variant and is now deserialized/yielded and included in the item type
   instead of silently terminating the stream.

3. Thread the event payloadContentType into each SSE descriptor and only
   JSON.parse JSON payloads; non-JSON (e.g. text/plain) payloads are
   passed through as the raw data string.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Opt the http-specs streaming/sse scenario (unnamed, named+terminal, retrieve) into the typespec-ts integration suite so the default structured-streaming codegen is exercised end-to-end against the real spector mock. The generated public surface confirms the operations return Promise<AsyncIterable<T>> with heterogeneous per-event dispatch and terminal-event handling.

JSONL is deferred from the integration baseline: its send() op exercises request-body (upload) stream typing, a pre-existing emitter gap unrelated to this response-streaming feature. JSONL response streaming remains covered by the unit-modular snapshot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Remove unrelated @typespec/http-client-python 0.35.1 churn from the lock
and keep only the @typespec/events, @typespec/sse, and @typespec/streams
workspace links required by typespec-ts's new streaming dependencies.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Add @azure/core-sse devDependency (with clean lockfile entries) and a
runtime integration test that exercises the generated SSE clients against
the http-specs mock server: unnamed message events, heterogeneous named
events with terminal [DONE] handling, and event-name-dispatched retrieve
streaming.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Move the @azure/core-sse version into the pnpm-workspace.yaml catalog and
reference it via catalog: in package.json, matching the repo policy that all
external dependencies use the catalog protocol.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Comment thread packages/typespec-ts/spector.config.yaml
Merge jsonlStreaming.md, sseUnnamedStreaming.md, and sseNamedStreaming.md
into a single streaming.md with three scenarios (the scenario runner splits
each file on H1, so one file holds multiple scenarios).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
…turedStreamInfo

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
…ating

Two structured-streaming correctness fixes:

- Non-terminal SSE events whose payload needs no model deserializer
  (primitive/scalar/enum) were silently dropped because no deserialize
  callback was emitted. Emit an identity deserializer so the raw payload
  (JSON-parsed value, or raw string for non-JSON content) is yielded.
  Add a regression scenario mixing a model and a text/plain scalar event.

- packageHasSseStreaming now mirrors getStructuredStreamInfo's gating
  (paging/LRO exclusions + streamMetadata & sseMetadata requirement) so
  @azure/core-sse is only injected when SSE streaming is actually generated.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d

@maorleger Maor Leger (maorleger) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is coming along quite nicely!! Thanks so much for all the effort in getting this together.

I still have lots to review, but the overall direction seems ok. I noted a few findings that we should fix though

Comment thread packages/typespec-ts/static/static-helpers/streamingHelpers.ts Outdated
Comment thread packages/typespec-ts/src/modular/helpers/operation-helpers.ts Outdated
Comment thread packages/typespec-ts/src/modular/helpers/operation-helpers.ts Outdated
Comment thread packages/typespec-ts/test/azure-modular-integration/streaming-sse.test.ts Outdated
Comment thread packages/typespec-ts/static/static-helpers/sseStreamingHelpers.ts Outdated
- Add streamingHelpers-browser.mts: uses asBrowserStream() and converts ReadableStream to AsyncIterable
- Add streamingHelpers-react-native.mts: re-exports browser variant
- Add sseStreamingHelpers-browser.mts: re-exports base (body already AsyncIterable)
- Add sseStreamingHelpers-react-native.mts: re-exports browser variant
- Fix terminal event name-aware matching in sseStreamingHelpers.ts (check descriptor by name first)
- Add content-type validation for JSONL vs SSE stream detection
- Add named event type discrimination for SSE return types (discriminated union)
- Update streaming test baselines for named event discriminated unions
- Clarify in SSE integration test that discriminated union enables type-safe narrowing

Follows the same pattern as get-binary-response polyfills. Enables:
- Node.js: StreamableMethod.asNodeStream() → AsyncIterable (default)
- Browser: StreamableMethod.asBrowserStream() → ReadableStream → AsyncIterable
- React-Native: Same as browser (browser APIs available)

Addresses PR review comments:
- r3815393091: Environment polyfills
- r3815434566: Content-type validation
- r3815531940: Terminal event name-aware matching
- r3815653900: Named event type discrimination with discriminated union

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5de9bff8-f217-4c66-9e30-bdc80256fed8
Include the SSE event name when JSON payload parsing fails and preserve the original error as the cause.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5de9bff8-f217-4c66-9e30-bdc80256fed8
Generate discriminated union return types for heterogeneous named SSE streams so callers can narrow payloads by event name. Update streaming operation baselines.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5de9bff8-f217-4c66-9e30-bdc80256fed8
…ed events in an envelope

Terminal events are now always consumed internally and never yielded, so the
declared item union is sound by construction. The terminal check runs after
descriptor resolution by event name (an unrelated event carrying the sentinel
data can no longer end the stream) and before deserialization (terminal
payloads are never yielded).

Named SSE events are wrapped in a { event, data } envelope so the generated
return type matches what the runtime helper yields. The envelope is applied
all-or-nothing via everyPayloadEventIsNamed to avoid a union mixing envelope
and bare shapes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Comment thread packages/typespec-ts/src/modular/helpers/operation-helpers.ts Fixed
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
Use ordinary JSON.stringify quoting instead of custom script-embedding escapes. Remove the dedicated utility and exotic-metadata tests while preserving SSE Spector coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bbec15a-04ed-41e4-9fae-e27932b80317
Include terminal constants in generated return types and yield them before stopping. Preserve named event envelopes with the default message name for unnamed terminals, keep unnamed streams payload-only, and update runtime, snapshots and Spector coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bbec15a-04ed-41e4-9fae-e27932b80317
const yielded = useEventEnvelope
? `({ event: ${JSON.stringify(event.eventName ?? "message")}, data: ${event.deserializeExpression} })`
: event.deserializeExpression;
parts.push(`deserialize: (data) => ${yielded}`);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this will be an issue?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Critical browser SSE cleanup and scalar deserialization issues remain, along with JSONL gating and breaking-release metadata corrections.

3 open findings
13 resolved since last review
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

🧠 Review effort: Lite

Comment thread packages/typespec-ts/src/modular/helpers/operation-helpers.ts
Comment thread packages/typespec-ts/src/modular/helpers/operation-helpers.ts
Comment thread packages/typespec-ts/static/static-helpers/sseStreamingHelpers.ts Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bbec15a-04ed-41e4-9fae-e27932b80317

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Browser SSE terminal cleanup fails with the pinned dependency, and structured-stream response aliases are misleading.

0 open findings

3 resolved since last review
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

🧠 Review effort: Lite

Comment thread packages/typespec-ts/static/static-helpers/getSseResponse.ts
Comment thread packages/typespec-ts/test/modular-unit/scenarios/operations/streaming.md Outdated
Comment thread packages/typespec-ts/static/static-helpers/sseStreamingHelpers.ts Outdated
Comment thread packages/typespec-ts/static/static-helpers/streamingHelpers-browser.mts Outdated
Comment thread packages/typespec-ts/static/static-helpers/getSseResponse.ts Outdated
event: EventMessage,
descriptors: SseEventDescriptor<T>[],
): SseEventDescriptor<T> | undefined {
if (event.event) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can event.event be empty string? Other falsy values would also reach the else block.

@l0lawrence Libba Lawrence (l0lawrence) Oct 8, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we initialize it to be "" so yes it can be that gets treated as eventType "message"

Comment thread packages/typespec-ts/static/static-helpers/streamingHelpers.ts
Comment thread packages/typespec-ts/src/modular/helpers/operation-helpers.ts Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bbec15a-04ed-41e4-9fae-e27932b80317
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bbec15a-04ed-41e4-9fae-e27932b80317
…tream on terminal event

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bbec15a-04ed-41e4-9fae-e27932b80317
- "@azure-tools/typespec-ts"
---

Generate structured JSONL and SSE streaming operations as `Promise<AsyncIterable<T>>` of deserialized items/events instead of raw binary `Uint8Array` bodies. Connection and modeled HTTP error validation are eager; payload deserialization is lazy. Generate streaming helpers only for supported MIME types and non-paging, non-LRO operations. Deserialize scalar SSE payloads into their declared client types. Dispatch unnamed discriminated SSE model variants by their payload discriminator and yield terminal payloads before stopping.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content here will be shown in the changelog once a new version is released. I suggest that we make it shorter.

? event.deserializeExpression
: String(sseEvent.payloadType.value);
}
} else {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that an event be nullable (sseEvent.payloadType.kind === "nullable")? For example:

model Payload {
  @encodedName("application/json", "wire_value")
  value: string;
  timestamp: utcDateTime;
}

@events
union NullableEvents {
  @Events.contentType("application/json")
  update: Payload | null,
}

@route("/receive")
op receive(): SSEStream<NullableEvents>;

The current deserializing behavior is

deserialize: (data) => ({
  event: "update",
  data: data === null ? null : data,  // <- should be payloadDeserializer(data)
}),

I think we should still use the deserializer if data is not null.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me verify but I don't think there is a linter preventing it and if the wire data could be data: null

isAsync: true,
isExported: true,
name,
propertyName: normalizeName(operation.name, NameType.Property),

@JialinHuang803 Jialin Huang (JialinHuang803) Oct 13, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

propertyName names the public method on the client or operation group, and it should come from getOperationName as well, like name. Otherwise, a method annotated with @clientName(exact("my_operation")) will become myOperation at the client level.

throw createRestError(result);
}

const contentType_1 = Object.entries(response.headers)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, why is it contentType_1, not contentType?

@l0lawrence Libba Lawrence (l0lawrence) Oct 13, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there was a contentType in here already so defautled to _1 - let me see about rename

} else if (descriptor.discriminator) {
discriminated.push(descriptor);
} else {
fallback ??= descriptor;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If variants are unnamed, nonterminal constants, like below:

@events
union ConstantEvents {
  @Events.contentType("text/plain")
  "cat",

  @Events.contentType("text/plain")
  "dog",
}

@route("/receive")
op receive(): SSEStream<ConstantEvents>;

The generated descriptors would be:

[
  { isTerminal: false, deserialize: () => "cat", contentType: "text/plain" },
  { isTerminal: false, deserialize: () => "dog", contentType: "text/plain" },
]

Will runtime fallback to the first descriptor no matter the response is "cat" or "dog"?

@l0lawrence Libba Lawrence (l0lawrence) Oct 13, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would, can add something to check for value to avoid that? right now I dont believe search uses unnamed events at all so we shouldn't run into this scenario yet at least

?.split(";", 1)[0]
.trim()
.toLowerCase();
if (contentType !== "text/event-stream" || !response.body) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the operation is declared like

@route("/receive")
op receive(): SSEStream<MessageEvents> | NoContentResponse;

which has a streaming response and a 204 response, will an error be thrown if response.body is empty which is not expected?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh I think it would, let me fix that

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:typescript Issues for @azure-tools/typespec-ts emitter lib:tcgc Issues for @azure-tools/typespec-client-generator-core library meta:website TypeSpec.io updates stale Mark a PR that hasn't been recently updated and will be closed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants