feat(sdk): implement sdk metadata attachments#3923
Conversation
response/request object may become undefined after the changes, but in our test case we can always assert they do exists.
docs: update sponsors copy
chore: add cloudflare spec
chore: add clerk spec
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
SseFn in every generated client (fetch / axios / ky / next / ofetch / angular) returns Promise<ServerSentEventsResult<TData, TError>>, but ServerSentEventsResult<TData, TReturn = void, TNext = unknown> — that second slot is the underlying AsyncGenerator's return-value type, not an error channel. HTTP errors are thrown from the initial promise or surfaced via onSseError; an async generator's .return() value has nothing to do with them. createSseClient itself signs as ServerSentEventsResult<TData> (no TError), and the inner async function* has no explicit return, so the real TReturn is void. Only the public wrapper type is wrong. Latent for ~9 months since d43ef3f (feat(client): add support for server-sent events). Harmless while users' SSE error responses were effectively unknown, but breaks every .return() call and every mock async generator the moment any SSE endpoint declares a concrete error response — they suddenly fail to satisfy an iterator-return contract that should never have existed. Drop TError from the Promise<ServerSentEventsResult<...>> return type so TReturn defaults to void. The TError generic parameter is preserved (renamed to _TError so noUnusedParameters lets it through, with an eslint-disable for the corresponding lint rule) so the SDK template, which emits <TResponse, TError, ThrowOnError> uniformly for every method, keeps working without codegen changes. Nuxt's SseFn uses a different shape and was unaffected.
…-dsl refactor: pydantic dsl
…chain refactor: rename expression to chain
refactor: valibot plugin
…urn-miswiring fix(client): SSE iterator's TReturn was the endpoint's HTTP error union
|
|
|
@SukkaW is attempting to deploy a commit to the Hey API Team on Vercel. A member of the Team first needs to authorize it. |
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3923 +/- ##
==========================================
- Coverage 37.75% 37.70% -0.05%
==========================================
Files 582 583 +1
Lines 20817 20886 +69
Branches 6064 6096 +32
==========================================
+ Hits 7859 7876 +17
- Misses 10543 10578 +35
- Partials 2415 2432 +17
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Pullfrog stalled The agent stopped emitting events for 305s and was killed by the activity-timeout watchdog. 91 events were processed before the failure. Recent agent stderr
|
There was a problem hiding this comment.
ℹ️ Minor suggestions inline — otherwise clean implementation.
Reviewed changes — Added metadata option to @hey-api/sdk plugin that attaches OpenAPI-derived metadata to generated SDK operations via Object.assign(), with boolean or granular object configuration. Works across flat, single, and byTags strategies, and introduces request schema hoisting to avoid duplicate generation.
- Add
metadataconfig option — Boolean orUserMetadataConfigobject with granular control overid,method,url,tags,requestSchema,responseSchema - Implement
withMetadatawrapper — UsesObject.assign()to attach metadata properties to operation functions - Hoist request schemas — New
createRequestSchemaAPI on validator plugins (zod, valibot) allows reusing request schema nodes between metadata and request validators - Test coverage — Added 4 snapshot test scenarios: metadata-by-tags, metadata-flat, metadata-single, metadata-partial
Kimi K2 | 𝕏
| exampleIntent(method, operation, plugin); | ||
| if (isMetadataEnabled(plugin)) { | ||
| const field = attachComment({ | ||
| node: $.field(createFnSymbol(plugin, item), (f) => |
There was a problem hiding this comment.
| node: $.field(createFnSymbol(plugin, item), (f) => | |
| if (isMetadataEnabled(plugin)) { | |
| const method = attachComment({ | |
| node: $.method(createFnSymbol(plugin, item), (m) => | |
| attachComment({ | |
| node: m, | |
| operation, | |
| plugin, | |
| }) | |
| .public() | |
| .static(!isAngularClient && !isInstance(plugin)), | |
| ).assign( | |
| withMetadata({ | |
| fn: implementFn({ | |
| operation, | |
| plugin, | |
| requestSchema, | |
| }), | |
| operation, | |
| plugin, | |
| requestSchema, | |
| tags, | |
| }), | |
| ), | |
| operation, | |
| plugin, | |
| }); | |
| node.do(method); | |
| exampleIntent(method, operation, plugin); |
There was a problem hiding this comment.
APIError: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.
There was a problem hiding this comment.
ℹ️ No new issues found with the incremental changes.
Reviewed incremental changes — The author dropped requestSchema from the metadata object (commit 28dcb6e). Instead of hoisting request schemas as named constants and referencing them in both requestValidator and metadata, the validator now embeds the schema inline via z.object({...}).parseAsync(data) and the metadata no longer carries a requestSchema property.
- Removes
requestSchemafrom attached metadata — Simplifies the public API surface - Eliminates hoisted schema constants — Reverts the code reuse optimization that created shared
zXxxDatasymbols - Regenerates all snapshot fixtures — Expected churn in
__snapshots__/directories
This addresses the concern that request schemas would bloat exports and leak internal zod details onto the operation metadata. The responseSchema reference remains in metadata, which is appropriate since response schemas are already emitted as named exports.
Kimi K2 | 𝕏

The PR fixes #3446 with metadata support.
When enabled, SDK operations are emitted via
Object.assign(...)and expose OpenAPI-derived metadata such as:idmethodurltagsresponseSchemaThis works across SDK operation strategies:
metadataoption is introduced to@hey-api/sdkwithbooleanor object form (granular control for schema output)v1renderer to attach the metadatatagsmetadata from OpenAPI operation tags.This is a PoC kinda PR. Ideally, we might wanna implement the resolver API so that everyone can customize/tailor their own desired output shape here.