Repository navigation
Support required cookies, bodies, and forms in RouteBuilder - #2366
Merged
Merged
Conversation
pmcelhaney
enabled auto-merge
September 1, 2026 21:51
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Required-body readiness can be incorrectly satisfied by .body(undefined), and the changeset currently marks a breaking public API change as a patch.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR expands the RouteBuilder API to support immutable cookies() and form() inputs, validates required cookie/body/form inputs across OpenAPI/Swagger variants, and updates serialization + UX (help output, REPL completions, diagnostics) to match the new capabilities.
Changes:
- Add cookies + form fluent APIs, required-input validation (OpenAPI 2 + OpenAPI 3), and “last entity wins” behavior between
body()andform(). - Implement cookie-header merging and form serialization (URL-encoded by default; text-only multipart when multipart is the sole declared form type).
- Update REPL completions, black-box journey, docs, and tests; adjust HTTP message printing to preserve multipart bodies.
File summaries
| File | Description |
|---|---|
| test-black-box/test_developer_journey.py | Extends the REPL developer journey to assert required request body behavior. |
| test-black-box/features/developer_journey.feature | Adds a new Gherkin step for required pet body readiness. |
| packages/repl/test/repl.test.ts | Updates completion expectations to include cookies( and form(. |
| packages/repl/src/repl.ts | Adds cookies( and form( to the REPL route-builder completion set. |
| packages/counterfact/test/fixtures/openapi/swagger2.yaml | Adds a Swagger 2 fixture covering required formData. |
| packages/counterfact/test/fixtures/openapi/multipart.yaml | Adds an OpenAPI 3 fixture for required multipart text-only form bodies. |
| packages/counterfact/docs/features/route-builder.md | Documents cookies/forms, required-input semantics, entity precedence, and multipart display. |
| packages/client/test/route-catalog.test.ts | Adds coverage for Swagger 2 consumes inheritance behavior. |
| packages/client/test/route-builder.test.ts | Adds extensive unit coverage for required cookie/body/form inputs, help output, and inspection output. |
| packages/client/test/route-builder.integration.test.ts | Adds socket-level integration tests for cookie merge + form serialization + precedence. |
| packages/client/test/raw-http-client.test.ts | Ensures request printing shows full multipart bodies including the closing boundary. |
| packages/client/test/package/client-consumer-smoke.mjs | Updates consumer smoke expectations for help() writing to console. |
| packages/client/src/route-catalog.ts | Extends catalog metadata to include consumes + OpenAPI 3 requestBody. |
| packages/client/src/route-builder.ts | Implements cookies/forms, required-input validation, entity precedence, and serialization. |
| packages/client/src/raw-http-client.ts | Fixes HTTP head/body splitting to preserve multipart bodies in printed output. |
| packages/client/src/index.ts | Exports the new RouteRequestBody type. |
| packages/client/README.md | Updates public docs for new methods and changed help() behavior. |
| package.json | Adds generator scripts for the new OpenAPI fixtures. |
| .github/skills/counterfact-maintenance/SKILL.md | Captures durable guidance for multipart display splitting + aligned request-builder changes. |
| .changeset/clear-multipart-display.md | Records the multipart display + help-output behavioral change for release notes. |
| .changeset/bright-forms-build.md | Records the route-builder cookies/body/form support + REPL completion changes for release notes. |
Review details
- Files reviewed: 21/21 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+160
to
+163
| this._body = options.body; | ||
| this._formParams = options.formParams ?? {}; | ||
| this._formSet = "formParams" in options; | ||
| this._bodySet = "body" in options && !this._formSet; |
github-merge-queue
Bot
removed this pull request from the merge queue due to no response for status checks
Sep 2, 2026
pmcelhaney
enabled auto-merge
September 7, 2026 00:46
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Sep 9, 2026
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.
Summary
cookies()andform()methods toRouteBuilderbody()andform()last-method-wins request entitiesBinary and file multipart parts remain intentionally unsupported.
Verification
@counterfact/clientconsumer and the changed developer black-box journey passedManual acceptance tests
body()is called, then sends successfully.Cookieheader orcookies(), and thatcookies()merges percent-encoded pairs with an existing header.formDatafields reports missing keys and sends URL-encoded data after matchingform()values are supplied.body()afterform(), orform()afterbody(), sends only the last entity while existing path, query, and header behavior remains unchanged.Repository learning check
.github/skills/counterfact-maintenance/SKILL.md