feat(openapi): cookie parameters#1582
Conversation
📝 WalkthroughWalkthroughAdds server-side OpenAPI cookie-parameter support for ChangesOpenAPI Cookie Parameter Support
Sequence DiagramsequenceDiagram
participant Client
participant Server
participant StandardOpenAPICodec
participant ZodValidator
Client->>Server: HTTP request with Cookie header
Server->>StandardOpenAPICodec: decode(request) for detailed input
StandardOpenAPICodec->>StandardOpenAPICodec: flatten Cookie header and parse into cookies object
StandardOpenAPICodec->>ZodValidator: provide decoded input including lazy cookies accessor
ZodValidator->>Server: validation result
Server->>Client: response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request implements support for cookie parameters in the OpenAPI generator and codec when using inputStructure: 'detailed'. It extends the generator loop to map cookies to cookie parameters, parses the Cookie header in the standard codec, and adds corresponding tests. Feedback is provided to improve the parseCookieHeader implementation by handling URL-encoded keys/values and stripping wrapping double quotes to ensure RFC 6265 compliance and robust validation.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds first-class cookie support to OpenAPI generation and the standard OpenAPI codec when inputStructure: 'detailed', so cookie inputs can be validated and documented as in: cookie parameters.
Changes:
- Generate OpenAPI
in: cookieparameters from acookieskey in detailed input schemas. - Decode the
Cookieheader into a lazily-evaluatedcookiesobject on the server-side codec. - Add generator/utility/codec tests plus design/plan docs for the feature.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/openapi/src/openapi-utils.test.ts | Adds coverage for toOpenAPIParameters(..., 'cookie'). |
| packages/openapi/src/openapi-generator.ts | Extends detailed input handling to include cookies → cookie. |
| packages/openapi/src/openapi-generator.test.ts | Adds detailed-input generator tests for cookie parameters + invalid cookies schema. |
| packages/openapi/src/adapters/standard/openapi-codec.ts | Parses the Cookie header and exposes it as input.cookies via a lazy getter. |
| packages/openapi/src/adapters/standard/openapi-codec.test.ts | Adds decode tests validating cookie parsing behavior and mutability. |
| docs/superpowers/specs/2026-06-11-openapi-cookie-parameters-design.md | Documents the design and scope for cookie parameter support. |
| docs/superpowers/plans/2026-06-11-openapi-cookie-parameters.md | Implementation plan with steps/tests for cookie parameter support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
docs/superpowers/specs/2026-06-11-openapi-cookie-parameters-design.md (1)
23-38: 💤 Low valueOptional: Add language specifier to fenced code block.
The architecture diagram code block lacks a language specifier. While this is a minor formatting issue, adding one (e.g.,
```textor```plaintext) improves consistency.As per static analysis hints: "Fenced code blocks should have a language specified (MD040)."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/specs/2026-06-11-openapi-cookie-parameters-design.md` around lines 23 - 38, Add a language specifier to the fenced code block that begins with "User Schema (Zod)" so the block is tagged (for example `text` or `plaintext`); locate the triple-backtick block containing the architecture diagram lines ("User Schema (Zod) z.object({ session_id: z.string() }) ..." through "validates cookies like any other input field") and change the opening fence to include a language (e.g., ```text) to satisfy the MD040 lint rule.Source: Linters/SAST tools
docs/superpowers/plans/2026-06-11-openapi-cookie-parameters.md (1)
416-416: ⚡ Quick winRemove hardcoded absolute path.
The command uses an environment-specific absolute path
/Users/me/Projects/github/orpcthat won't work for other developers.💡 Proposed fix
-cd /Users/me/Projects/github/orpc && pnpm test --filter `@orpc/openapi` +pnpm --filter `@orpc/openapi` testor use repository root variable:
-cd /Users/me/Projects/github/orpc && pnpm test --filter `@orpc/openapi` +cd $(git rev-parse --show-toplevel) && pnpm --filter `@orpc/openapi` test🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-06-11-openapi-cookie-parameters.md` at line 416, The hardcoded absolute path in the test command ("cd /Users/me/Projects/github/orpc && pnpm test --filter `@orpc/openapi`") will fail for other devs; change it to use the repository root dynamically (for example by using git rev-parse --show-toplevel or an environment variable like REPO_ROOT/GITHUB_WORKSPACE) or run pnpm from the repo root via pnpm's directory option, so the command becomes portable and no longer depends on /Users/me/Projects/github/orpc.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/plans/2026-06-11-openapi-cookie-parameters.md`:
- Around line 263-314: Add two unit tests after the existing cookie tests that
call codec.decode (using serializer.deserialize.mockReturnValue(undefined), the
same URL/procedure setup and headers) to cover malformed cookie pairs and values
containing '=': one test with header 'cookie': 'valid=value;
malformed_no_equals; another=good' expecting input.cookies toEqual { valid:
'value', another: 'good' }, and another with header 'cookie': 'token=eyJhbGc=;
session=base64data==' expecting input.cookies toEqual { token: 'eyJhbGc=',
session: 'base64data==' }; keep the same use of input.cookies, serializer,
codec.decode and procedure identifiers as in existing tests.
In `@docs/superpowers/specs/2026-06-11-openapi-cookie-parameters-design.md`:
- Line 113: Update the examples to normalize the Cookie header before parsing:
replace direct access to request.headers['cookie'] with
flattenHeader(request.headers['cookie']) and use that result as the argument to
parseCookieHeader; ensure the examples import or reference flattenHeader from
'`@orpc/standard-server`' so the code demonstrates proper normalization of string
| string[] | undefined per RFC 6265.
- Around line 132-149: Add a new test block in
packages/openapi/src/adapters/standard/openapi-codec.test.ts that exercises
parseCookieHeader (and the higher-level decode() path that uses it) with the
listed edge cases: malformed pairs without '=', values containing '=', empty
values, leading/trailing whitespace in keys and values, and multiple Cookie
headers (use flattenHeader behavior). For each case assert that decode(...)
(with inputStructure: 'detailed') produces the expected cookies object (graceful
handling for malformed pairs, correct splitting when '=' is in the value, empty
string for empty values, trimmed keys/values, and merged results for multiple
headers). Ensure tests also include the no-Cookie and malformed-header
expectations already described so coverage is complete.
- Around line 87-95: The parseCookieHeader function mishandles pairs without '='
because it uses indexOf('=') slicing even when idx === -1; update
parseCookieHeader to detect idx === -1 and handle it safely by trimming the
pair, skipping empty strings, and treating a no-equals token as a key with an
empty string value (or skipping entirely if the key is empty); keep the normal
behavior when idx >= 0 (key = slice(0, idx).trim(), value = slice(idx+1).trim())
and return the resulting Record<string,string> accordingly.
In `@packages/openapi/src/adapters/standard/openapi-codec.ts`:
- Around line 24-35: The current parseCookieHeader function incorrectly handles
URL-decoding and quoted cookie values; replace its manual split/indexOf logic in
parseCookieHeader with the cookie library's parsing (use cookie.parse) so values
are URL-decoded and quotes handled consistently with `@orpc/server`, and update
any imports to include cookie; also add unit tests covering URL-encoded and
quoted cookie values to validate input.cookies behavior matches
packages/server's cookie handling.
---
Nitpick comments:
In `@docs/superpowers/plans/2026-06-11-openapi-cookie-parameters.md`:
- Line 416: The hardcoded absolute path in the test command ("cd
/Users/me/Projects/github/orpc && pnpm test --filter `@orpc/openapi`") will fail
for other devs; change it to use the repository root dynamically (for example by
using git rev-parse --show-toplevel or an environment variable like
REPO_ROOT/GITHUB_WORKSPACE) or run pnpm from the repo root via pnpm's directory
option, so the command becomes portable and no longer depends on
/Users/me/Projects/github/orpc.
In `@docs/superpowers/specs/2026-06-11-openapi-cookie-parameters-design.md`:
- Around line 23-38: Add a language specifier to the fenced code block that
begins with "User Schema (Zod)" so the block is tagged (for example `text` or
`plaintext`); locate the triple-backtick block containing the architecture
diagram lines ("User Schema (Zod) z.object({ session_id: z.string() }) ..."
through "validates cookies like any other input field") and change the opening
fence to include a language (e.g., ```text) to satisfy the MD040 lint rule.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 98147f30-2739-4d52-a9a3-6c8410a7370e
📒 Files selected for processing (7)
docs/superpowers/plans/2026-06-11-openapi-cookie-parameters.mddocs/superpowers/specs/2026-06-11-openapi-cookie-parameters-design.mdpackages/openapi/src/adapters/standard/openapi-codec.test.tspackages/openapi/src/adapters/standard/openapi-codec.tspackages/openapi/src/openapi-generator.test.tspackages/openapi/src/openapi-generator.tspackages/openapi/src/openapi-utils.test.ts
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — adds cookies as a supported key in inputStructure: 'detailed' mode, generating in: cookie OpenAPI parameters and parsing the Cookie request header during server-side decode.
- Add
cookiesto generator loop — extended the'params', 'query', 'headers'array to include'cookies'inopenapi-generator.ts, mapping it toparameterIn: 'cookie'. Updated the detailed-input error message to document the new key. - Parse
Cookieheader in codec — addedparseCookieHeaderhelper (splits on;, handles missing=, trims, skips empty segments) and a lazycookiesgetter/setter on the detailed decode return object inopenapi-codec.ts, usingflattenHeaderfrom@orpc/standard-serverfor header normalization. - Test coverage — generator tests for cookies-only, combined cookies+headers+query+body, and invalid non-object cookies; codec tests for parsing, absent header, settability, pairs without
=, and values containing=;toOpenAPIParameterscookie test verifying nostyle/explode/allowEmptyValue/allowReservedare emitted.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
- Replace custom parseCookieHeader with cookie.parse to align with @orpc/server cookie helper behaviour (RFC 6265 compliant) - Add cookie as a dependency of @orpc/openapi - Add tests for URL-encoded values and base64 values with = padding
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/openapi/src/adapters/standard/openapi-codec.ts (1)
72-76: [openapi-codec] Cookie header lookup is safe for standard-server inputs; consider a small case-insensitive fallbackNode’s
IncomingMessage.headersand Fastify’sraw.headersexpose lowercased header keys, and thestandard-server-node/standard-server-fastifyadapters pass those through. Forfetch-style inputs and API Gateway HTTP API (v2) events, header keys are also lowercased in practice, sorequest.headers.cookieshould work with real adapter-produced requests. SinceStandardHeadersitself doesn’t enforce casing and the unit tests use lowercasecookie, adding a fallback likerequest.headers.cookie ?? request.headers['Cookie']would improve robustness for manually-constructed inputs.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/openapi/src/adapters/standard/openapi-codec.ts` around lines 72 - 76, The cookies getter (get cookies) uses flattenHeader(parseCookie(flattenHeader(request.headers.cookie) ?? '')) which assumes a lowercase 'cookie' header; update it to fall back to a case-insensitive lookup (e.g., use request.headers.cookie ?? request.headers['Cookie'] or check both keys) before calling flattenHeader/parseCookie, and then store the parsed value via Object.defineProperty as before so manually-constructed or differently-cased headers still produce correct cookies; refer to the getter name "cookies", helper "flattenHeader", and "parseCookie" to locate the code to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/openapi/src/adapters/standard/openapi-codec.ts`:
- Around line 72-76: The cookies getter (get cookies) uses
flattenHeader(parseCookie(flattenHeader(request.headers.cookie) ?? '')) which
assumes a lowercase 'cookie' header; update it to fall back to a
case-insensitive lookup (e.g., use request.headers.cookie ??
request.headers['Cookie'] or check both keys) before calling
flattenHeader/parseCookie, and then store the parsed value via
Object.defineProperty as before so manually-constructed or differently-cased
headers still produce correct cookies; refer to the getter name "cookies",
helper "flattenHeader", and "parseCookie" to locate the code to change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9ae6c1e4-d699-4aba-b088-75aabc7944dd
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
packages/openapi/package.jsonpackages/openapi/src/adapters/standard/openapi-codec.test.tspackages/openapi/src/adapters/standard/openapi-codec.ts
✅ Files skipped from review due to trivial changes (1)
- packages/openapi/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/openapi/src/adapters/standard/openapi-codec.test.ts
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — replaced the hand-rolled parseCookieHeader with the cookie npm package for RFC 6265-compliant cookie parsing, added tests for URL-decoded and base64-padded values, and added the cookie dependency.
- Switched to
cookiefor header parsing — removed the customparseCookieHeaderhelper inopenapi-codec.tsand replaced it withparsefrom thecookiepackage, which handles URL-decoding, quoted values, and other edge cases that the hand-rolled parser did not. - Extended test coverage — added tests for URL-encoded values (
hello%20world→hello world), percent-encoded special chars (%40→@), and base64 values with trailing=padding, all validated by thecookiepackage's parsing behavior.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

Motivation
When building a server with endpoints that must explicitly declare which cookies they require — and receive typed access to those values as part of the request input — there was no way to express this through oRPC's OpenAPI integration. The generated spec had no
in: cookieparameter entries, and the decoded input object had nocookieskey.While oRPC provides cookie helpers (
getCookie,setCookie,deleteCookie) for manual cookie access within handlers, this PR addresses a different need: treating cookies as first-class, typed input parameters — declared in the schema, validated at the boundary, and visible in the generated OpenAPI spec — in the same wayquery,headers, andparamsare handled today.What this does
Adds
cookiesas a supported key ininputStructure: 'detailed'mode:Spec generation (
openapi-generator.ts): the generator now recognisescookiesas a fifth top-level key alongsideparams,query,headers, andbody. Each property of thecookiesschema is emitted as anin: cookieparameter object in the OpenAPI spec.Server-side decode (
openapi-codec.ts): thedecode()method now exposes a lazycookiesgetter on the detailed input object. It parses the incomingCookierequest header (using the same lazy-evaluation pattern already used forquery) and returns aRecord<string, string>. UsesflattenHeaderfrom@orpc/standard-serverfor correct header normalisation.Usage
Generated spec:
What is NOT included in this PR (initial implementation)
I'd love to hear your feedback on this approach. If there are aspects of the design you'd like to see changed, or if you have suggestions on how to best continue this work (e.g. compact mode support, client-side encoding), I'm happy to follow your guidance.
Thank you,
Rafał
Summary by CodeRabbit
Documentation
New Features
Tests