Commit 8fde19b
Validate SSEStream union parameter has @events decorator (#8951)
SSEStream accepted unions without `@events` decorator, generating
incorrect schemas. This validation ensures proper event stream
definitions at compile time.
## Changes
- **Added validation** in `packages/sse/src/validate.ts`:
- Traverse all models during validation phase
- Check streams with `text/event-stream` content-type
- Verify streamOf type is a union with `@events` decorator
- Report `sse-stream-union-not-events` diagnostic on failure
- **Added diagnostic** `sse-stream-union-not-events` in
`packages/sse/src/lib.ts`
- **Added tests** covering invalid/valid SSEStream usage and HttpStream
with SSE content-type
## Example
This now fails validation:
```typespec
union BasicUnion {
userconnect: UserConnect,
}
op subscribe(): SSEStream<BasicUnion>; // Error: union must have @events
```
This compiles:
```typespec
@events
union BasicUnion {
userconnect: UserConnect,
}
op subscribe(): SSEStream<BasicUnion>; // OK
```
Fixes #8888
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `telemetry.astro.build`
> - Triggering command: `node
/home/REDACTED/work/typespec/typespec/website/node_modules/.bin/../astro/astro.js
build` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/microsoft/typespec/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>SSEStream should NOT accept a union model without the
events decorator</issue_title>
> <issue_description>This definition
>
> ```ts
> import "@typespec/streams";
> import "@typespec/sse";
> import "@typespec/events";
>
> using SSE;
>
>
> model UserConnect {
> name: string;
> }
>
> union BasicUnion {
> userconnect: UserConnect,
> }
> op subscribe(): SSEStream<BasicUnion>;
> ```
>
> Builds but generates the wrong schema (instead of item schema with all
the right properties)
>
> ```ts
> import "@typespec/streams";
> import "@typespec/sse";
> import "@typespec/events";
>
> using SSE;
>
>
> model UserConnect {
> name: string;
> }
>
> @TypeSpec.Events.events
> union BasicUnion {
> userconnect: UserConnect,
> }
> op subscribe(): SSEStream<BasicUnion>;
> ```
>
> Generates the correct itemSchema.
>
> Ultimately this is not a responsibility of the OpenAPI3 emitter to
check for this, but rather the SSE library should fail building when
being passed a union model as a generic type parameter value when that
union model DOES NOT have the required decorator.
> This will be handled in a separate issue/pull request
>
> _Originally posted by @baywet in
#8888 (comment)
> </issue_description>
>
> <agent_instructions>before committing any file, run `npx prettier
--write filePath` to ensure they are formatted correctly.
> once you're done with the changes, run `npx @chronus/chronus add` and
select bugfix to add an entry in the changelog</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> <comment_new><author>@timotheeguerin</author><body>
> Also note that as `SSEStream` is just defined as `HttpStream<Type,
"text/event-stream">;`
>
> that also might need to validate when `text/event-stream` is
used</body></comment_new>
> </comments>
>
</details>
- Fixes #8950
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Signed-off-by: Vincent Biret <[email protected]>
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: baywet <[email protected]>
Co-authored-by: Vincent Biret <[email protected]>
Co-authored-by: Timothee Guerin <[email protected]>1 parent 1dde0d1 commit 8fde19b
File tree
4 files changed
+152
-3
lines changed- .chronus/changes
- packages/sse
- src
- test
4 files changed
+152
-3
lines changedLines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
11 | 18 | | |
12 | 19 | | |
13 | 20 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| 2 | + | |
2 | 3 | | |
| 4 | + | |
| 5 | + | |
3 | 6 | | |
4 | 7 | | |
5 | 8 | | |
6 | 9 | | |
| 10 | + | |
7 | 11 | | |
8 | 12 | | |
9 | 13 | | |
| |||
24 | 28 | | |
25 | 29 | | |
26 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
26 | 111 | | |
0 commit comments