Skip to content

feat: add res.cookie, res.clearCookie, and fix writeHead header merging#398

Merged
avoidwork merged 12 commits into
masterfrom
feat/cookie-handling-and-writehead-merge
May 23, 2026
Merged

feat: add res.cookie, res.clearCookie, and fix writeHead header merging#398
avoidwork merged 12 commits into
masterfrom
feat/cookie-handling-and-writehead-merge

Conversation

@avoidwork
Copy link
Copy Markdown
Owner

@avoidwork avoidwork commented May 23, 2026

Description

Adds res.cookie(name, value, opts) and res.clearCookie(name, opts) to the response object for setting and clearing HTTP cookies. Fixes writeHead() to merge passed headers with existing response headers via res.getHeaders(), preserving cookies and other headers set before res.send() is called.

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bugfix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation writeup
  • CI / build / tooling

Testing

All 365 existing tests pass. New tests added:

  • serializeCookie basic cookie generation with path
  • serializeCookie encoding (default encodeURIComponent, custom encode function, encode: false)
  • serializeCookie maxAge with expires date conversion
  • serializeCookie httpOnly, secure, sameSite (strict/lax/none/pass-through)
  • serializeCookie custom domain and path options
  • createCookieHandler sets cookie via setHeader with options
  • createClearCookieHandler clears cookie with expired date and domain option
  • writeHead merge headers with existing response headers
  • Integration tests: res.cookie followed by res.send preserves set-cookie header
  • Integration tests: multiple cookies preserved with set-header and writeHead merge
  • Integration tests: set-cookie header alongside other headers from res.header

Tests run via npm test (lint + full test suite).

Coverage

  • 100% line coverage maintained

Checklist

  • npm run lint passes
  • Tests pass with 100% line coverage
  • No forbidden patterns used
  • Conventional Commit style applied

- Add serializeCookie() with full options support (domain, path, maxAge,
  expires, httpOnly, secure, sameSite, encode)
- Add res.cookie(name, value, opts) to #decorateResponse
- Add res.clearCookie(name, opts) for clearing cookies
- Fix writeHead() to merge headers from res.getHeaders() instead of
  passing directly, preserving cookies and other headers set before
  res.send()
- Update TypeScript definitions with CookieOptions, ClearCookieOptions,
  WoodlandResponse interfaces
- Add 27+ new unit tests and 3 integration tests
- response.js: 100% line coverage maintained
@avoidwork avoidwork self-assigned this May 23, 2026
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 23, 2026

🤖 Augment PR Summary

Summary: Adds first-class cookie helpers to Woodland responses and fixes a long-standing header-loss issue when writing responses.

Changes:

  • Introduced `serializeCookie()` plus `res.cookie()` / `res.clearCookie()` decorators that append values to the `set-cookie` header.
  • Updated `writeHead()` to merge passed headers with existing response headers from `res.getHeaders()` so pre-set headers (incl. cookies) aren’t lost.
  • Extended unit coverage for cookie serialization/options and for `writeHead()` merge/override behavior.
  • Added integration tests verifying cookies survive `res.send()` and coexist with other headers.
  • Updated README/API docs, TypeScript definitions, and regenerated `dist/` bundles.

Technical Notes: Cookie options support domain/path/maxAge→Max-Age+Expires, httpOnly/secure, sameSite normalization, and configurable encoding (including disabled encoding).

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 4 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread src/response.js Outdated
Comment thread src/response.js Outdated
Comment thread tests/integration/cookie.test.js Outdated
Comment thread tests/unit/response.test.js Outdated
avoidwork added 7 commits May 23, 2026 15:14
- README: Add res.cookie/res.clearCookie to Response Helpers
- API: Add full cookie/res.clearCookie docs with option tables
- OVERVIEW: Add cookie handling to Security Features and Response Methods
- FLOWS: Update #decorateResponse flow, response methods table, writeHead comment
- Remove redundant second parameter in else branch
- Move existing assignment inside conditional
- No third parameter passed when headers is undefined
- Check typeof instead of truthiness to avoid encodeFn being set to boolean
- encode: true now uses encodeURIComponent instead of throwing
- encode: false uses passthrough function
- encode: function uses the custom function
- Don't recompute Expires when caller provides their own expires date
- clearCookie now produces Max-Age=0 with Expires=Thu, 01 Jan 1970
- createCookieHandler now uses getHeader+setHeader to accumulate cookies
- clearCookieHandler appends rather than replaces existing set-cookie values
- assert on both cookie count and values in integration test
- Overwrite coverage report with accurate numbers from coverage.txt
- Fix table: response.js 99.12% line, 95.71% branch, woodland.js 98.63%/92.16%
- Update FLOWS.md cookie flow to show array append semantics
- Update FLOWS.md clearCookie from maxAge: -1 to maxAge: 0
@avoidwork
Copy link
Copy Markdown
Owner Author

augment review

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread src/response.js Outdated
Comment thread types/woodland.d.ts Outdated
avoidwork added 4 commits May 23, 2026 16:17
Write tests for previously uncovered code:
- writeHead(res, undefined) else branch
- createCookieHandler/clearCookieHandler non-array getHeader
- Missing middleware route throws
- Origin validation in allowlist but too long
- Disallowed origin returns 403
- Safe origin returns ACA-Origin header

Cover edge cases:
- isSafeOrigin: length check at >255
- cookie handler: string-to-array conversion

Use node:coverage ignore for intentionally unreachable/race-condition code:
- Body limit handler (timing issue)
- isSafeOrigin: typeof check (always string from HTTP), control chars (HTTP parser strips)
- Use 'headers !== null && typeof headers === OBJECT' check
- Call res.getHeaders() only if method exists and is a function
- Handle non-object headers (null, string, number) by passing directly
- Add test for null headers to writeHead
Send supports streams, buffers, strings, and objects with toString().
The previous string-only type would reject valid usage at compile time.
@avoidwork avoidwork merged commit 09ac653 into master May 23, 2026
3 checks passed
@avoidwork avoidwork deleted the feat/cookie-handling-and-writehead-merge branch May 23, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant