feat: export a companion interface alongside each payload class#421
Open
jonaslagoni wants to merge 10 commits into
Open
feat: export a companion interface alongside each payload class#421jonaslagoni wants to merge 10 commits into
jonaslagoni wants to merge 10 commits into
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add payloadClassPreset() and shared withCompanionInterfaceExport() to utils.ts - Refactor parameters.ts to use the shared export-rewrite helper - Insert payloadClassPreset() after TS_COMMON_PRESET in the payload chain - Apply the companion-interface export rewrite across all payload loops Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add payloadUnionType/payloadInstanceExpression/renderPayloadNormalization emitters
- Dual {Class, ClassInterface} import for object payloads in addPayloadsToDependencies
- Widen publish/request input sites: NATS core/jetstream/request, Kafka, MQTT,
AMQP queue/exchange, WebSocket, HTTP client; normalize before marshal
- Thread messageUnionType through render types so NATS client publish wrappers
accept the Interface | Class union (HTTP client inherits via its context type)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add 'Companion Interface' section to docs/generators/payloads.md - Regenerate ecommerce-asyncapi-payload example with companion interfaces - Demonstrate plain-object publish ergonomics in the example (index.ts + README) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerated test/runtime/typescript/src with companion interfaces on object payloads and widened publish/request input sites. Verified: payloads parity spec, HTTP client (114), WebSocket, NATS/Kafka/MQTT/AMQP/EventSource broker suites all pass. (Pre-existing FormatTime env failure and flaky NATS request/reply-under-parallel-load are unrelated to this change.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- payload.spec: object payloads (SimpleObject2, SimpleObject) gain interface + retyped ctor + dual export; const 'type' correctly omitted from the interface - channels.spec: OpenAPI HTTP client Pet payload widens (import, context payload field, body normalization); non-object response + receive sites unchanged Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The object-payload branch of payloadUnionType/payloadInstanceExpression/ renderPayloadNormalization now delegates to the parameter emitters, single- sourcing the Interface|Class union and instanceof-guard format while keeping the object-vs-module gate explicit. (Shared withCompanionInterfaceExport export helper was already consolidated in Phase 3.) Pure refactor - output unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
I suggest maybe taking a look at this PR: #422. We want the same thing, but I do it slightly different. 😄 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Give every generated object payload a plain-data companion
interface <Name>Interface, exported alongside the class, and widen the payload input sites across all channel/client protocols to accept<Name>Interface | <Name>— normalizing to a class instance before.marshal(). This is the exact ergonomic #413 shipped for parameters, now applied to payloads.Callers can pass a plain object wherever a payload is accepted — no
new <Name>(...)required:How
payloadClassPreset) prependsinterface <Name>Interface {…}and retypes the constructor toconstructor(input: <Name>Interface), reusing the existingbuildParametersInterfaceBody. It's inserted afterTS_COMMON_PRESETso it augments (not replaces) the validation/union/primitive chain and never touchesclass.additionalContent.withCompanionInterfaceExport) rewritesexport { <Name> }→export { <Name>, <Name>Interface }, gated on the interface actually being present.parameters.tswas refactored to share this helper so the two generators can't diverge.payloadUnionType/payloadInstanceExpression/renderPayloadNormalizationemitters (object payloads delegate to the parameter primitives for a single-sourced format; non-object payloads pass through unchanged). Widened input sites: NATS core/jetstream/request, Kafka, MQTT, AMQP queue/exchange, WebSocket, and HTTP client. Object payloads also get a dual{Class, ClassInterface}import; amessageUnionTypefield is threaded through the render pipeline so the NATS client wrapper accepts the union too (HTTP client inherits it via its context type).What's NOT changed
coreReplyreturn type and EventSourcesendEventstay class-typed (matches feat: export a companion interface alongside each parameter class #413).schemas/are unchanged.Testing
constdiscriminators correctly omitted from the interface; non-object payloads unchanged. Per-protocol tests assert the widened input type + normalization; excluded sites verified untouched..marshal()output; HTTP client, WebSocket, and NATS/Kafka/MQTT/AMQP/EventSource broker suites pass against live Docker brokers.docs/generators/payloads.md; theecommerce-asyncapi-payloadexample regenerated and updated to demonstrate the plain-object ergonomic.Compatibility (not a breaking change)
Regenerating produces a diff, but the public-facing interface only gains or widens — nothing is removed or narrowed — so existing consumer source code keeps compiling without changes:
new <Name>({...})still compiles).<Name>Interface(additive).payloadfield widen from<Name>to<Name>Interface | <Name>— callers passing a class instance still type-check.So this is a backward-compatible feature (
feat:→ minor), matching #413's compatibility posture. (The only theoretical exception is exotic type-level reflection that pins a widened parameter to exactly<Name>— not a normal usage pattern.)🤖 Generated with Claude Code