feat: add channels organization option (flat / tag / path)#398
Merged
Conversation
…ption Add organization: 'flat' | 'tag' | 'path' to zodTypescriptChannelsGenerator (default 'flat', no behavior change) and optional tags/pathSegments/method grouping metadata to TypeScriptChannelRenderedFunctionType and SingleFunctionRenderType. Consumed only by finalizeGeneration in later phases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add tagged AsyncAPI v3 fixture (asyncapi-organization.json), 4 dedicated
per-style codegen configs generating into src/{openapi,asyncapi}-{tag,path}-organization,
wire generate:organization + test:organization scripts, hand-written expected
reference barrels under test/channels/organization/expected/, and 4 runtime
specs asserting the grouped surface. Generation runs clean (still flat); the
14 organization assertions fail for the right reason (grouped exports absent).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an organization describe block to channels.spec.ts: flat regression guard (passes, byte-identical namespace barrel), plus tag/path grouped-shape and grouping-metadata assertions that fail because finalizeGeneration/metadata population are not yet implemented. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add resolveGroupingMetadata + attachGroupingToRenders + splitAddressSegments helpers to channels/utils.ts. Populate tags/pathSegments on each render across all 7 AsyncAPI protocols (per-operation in generateForOperations, per-channel in generateForChannels) and tags/pathSegments/method for OpenAPI in the processOperation walker; copy the fields through each addRendersToExternal. Grouping fields added to HttpRenderType. Metadata unit test passes; flat output unchanged (15 existing channel snapshots green). tag/path barrel branching lands in Phase 5. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…art 2)
Extract renderChannelIndex into channels/utils.ts (with groupByTag, groupByPath,
renderObjectLiteral) and call it from finalizeGeneration. flat stays byte-identical
to today; tag/path emit a grouped 'export const <protocol> = {...} as const' literal
per protocol (tag: one level, untagged bucket; path: nested by segments, method leaf
for OpenAPI / function-name leaf for AsyncAPI, with collision warning). All 4 unit
org tests and 14 runtime org specs green; 17 channel unit tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an Organization subsection to docs/generators/channels.md (flat/tag/path, tag-source precedence, path leaf method-vs-function, v2 no-channel-tags caveat, before/after call sites) and an Organizing subsection to the openapi-http-client example README. Options-table row is regenerated from Zod in Phase 7. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerate schemas/configuration-schema-0.json and -0-with-docs.json from Zod (only the organization enum added). Add the organization row to the channels options table. New openapi-tag/openapi-path barrel snapshots recorded; all existing flat snapshots unchanged (627 tests, 78 snapshots green). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add channels-organization-utils.spec.ts covering splitAddressSegments, groupByTag (untagged bucket), groupByPath (method vs function-name leaf, collision keep-first), renderObjectLiteral (nesting + identifier quoting), and renderChannelIndex (flat/tag/empty). Grouping attach logic is already shared via resolveGroupingMetadata + attachGroupingToRenders; no any, explicit return types throughout. 637 unit tests + 78 snapshots green, lint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…h leaf Addresses two review points on the channels `organization` option. 1. AsyncAPI `path` leaf is now a derived action verb (publish, subscribe, jetStreamPublish, …) mirroring the OpenAPI method leaf, instead of the verbose function name. On a leaf collision the unique function name is used as a fallback so no function is silently dropped; a path segment that collides with an existing leaf now warns and skips instead of clobbering. 2. Consolidated the duplicated organization plumbing: a single shared addRendersToExternal (protocol-keyed) replaces 7 byte-identical per-protocol copies plus the inline openapi block, and a single attachGroupingMetadata helper folds the resolveGroupingMetadata + attachGroupingToRenders pair used at ~13 call sites. The grouping field set now lives in one place; a new protocol gets organization support for free. Updated docs, Zod description + regenerated schemas, groupByPath unit tests, and the AsyncAPI-path runtime expected/generated/spec artifacts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ALagoni97
approved these changes
Jul 9, 2026
# Conflicts: # src/codegen/generators/typescript/channels/openapi.ts # src/codegen/types.ts
Contributor
Author
|
🎉 This PR is included in version 0.74.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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.
Overview
Adds an
organization: 'flat' | 'tag' | 'path'option to the TypeScript channels generator. It controls how generated functions are surfaced in the barrelindex.ts— the per-protocol<protocol>.tsfunction code never changes, only the re-export shape does.flat(default) — today's behavior, byte-for-byte identical.tag— groups functions one level deep under their API tag (operation tag → v3 channel tag →untaggedbucket). Leaf names verbatim.path— nests functions by URL path / channel address segments; leaf is the HTTP method for OpenAPI and a clean action verb (publish,subscribe,jetStreamPublish, …) for AsyncAPI, mirroring the method leaf. On a leaf collision the unique function name is used as a fallback so nothing is dropped.Applies to both OpenAPI (
http_client) and all 7 AsyncAPI protocols.Breaking change?
No.
organizationdefaults to'flat', which reproduces current output exactly (guarded by an unchanged snapshot + byte-identical runtime regeneration). New shapes are opt-in. Minor (feat:).Approach (Expected Output First / TDD)
Implemented across 8 commits following the approved plan:
tags/pathSegments/methodmetadata on render types.src/*-organization, hand-written expected reference barrels, RED runtime specs.resolveGroupingMetadata/attachGroupingToRenders); OpenAPI walker + all 7 protocols.finalizeGenerationbranches via a newrenderChannelIndexhelper (groupByTag/groupByPath/renderObjectLiteral).Review follow-up
Two points raised in review, addressed in a follow-up commit:
pathleaf. The leaf was the verbose function name (nats.user.signedup.publishToSendUserSignedup), which defeats the point of nesting. It's now a derived action verb (nats.user.signedup.publish) mirroring the OpenAPI method leaf, via aChannelFunctionTypes → verbmap. Collisions fall back to the unique function name (previously the second function was silently dropped), and a path segment that collides with an existing leaf now warns + skips instead of clobbering.addRendersToExternalfunctions + theresolveGroupingMetadata/attachGroupingToRenderspair wired at ~13 sites. Consolidated into a single sharedaddRendersToExternal(protocol-keyed) and a singleattachGroupingMetadatahelper inutils.ts. The grouping field set now lives in one place — a new protocol getsorganizationsupport for free. ~210 lines of duplication removed.Verification
npm run build✓ ·npm run lint(max-warnings 0) ✓prepare:prlockfile drift intest/runtime/typescript/was machine-local only — CI's runtime prep + suites pass cleanly.🤖 Generated with Claude Code