Commit Graph

2 Commits

Author SHA1 Message Date
Sékou Dayifourou KEITA d29ee0eebb fix(route-handlers): align Allow and default-export behavior with Next.js (#497)
* fix: ensure route handlers send correct Allow header

* Inline route handler Allow helpers in RSC entry

* fix: refresh entry snapshots and fmt

* fix(route-handlers): align Allow and default-export behavior with Next.js

* fix(route-handlers): align default-export behavior with Next.js per review

Follow-up for PR #497 review feedback (requested changes).

Changes:

- stop throwing on default export in route handlers

- log dev-only warning when default export is detected

- ignore default export for dispatch so default-only handlers return 405

- keep sorted Allow on implicit OPTIONS and no Allow on 405

- update integration/e2e tests, snapshots, and tracking notes
2026-03-13 12:16:46 +00:00
Nathan Nguyen af0a839a67 fix: preserve multiple Set-Cookie headers in response merging (#297)
* fix: preserve multiple Set-Cookie headers in prod-server and worker entry

The response header merging in prod-server.ts and the generated Cloudflare
worker entry used Record<string, string> which flattened multiple Set-Cookie
headers — the last value won, or cookies with Expires dates got corrupted
by comma-joining.

Extract mergeResponseHeaders() helper that uses getSetCookie() to preserve
array-valued Set-Cookie headers. Apply the same fix to the worker entry
template in deploy.ts using the Headers API.

Fixes #295

* fix: address review feedback on Set-Cookie header preservation

- Add `as string` cast in deploy.ts worker entry for x-middleware-request-*
  header unpacking (matches prod-server.ts)
- Normalize Vary header with Array.isArray check in sendCompressed to handle
  the widened type correctly
- Add edge-case test for middleware cookie as plain string (not array)

* fix: apply Set-Cookie fix to example workers, remove redundant toLowerCase

- Fix the same Set-Cookie flattening bug in hand-written example worker
  entries (pages-router-cloudflare, realworld-api-rest)
- Remove 4 redundant .toLowerCase() calls — Headers.forEach() always
  yields lowercase keys

* fix: add missing as string cast in deploy.ts middleware header collection

* refactor: extract mergeHeaders to shared vinext/server/worker-utils

The mergeHeaders function was duplicated in both example worker entries
(pages-router-cloudflare, realworld-api-rest) and the deploy.ts template.
Extract it to a shared module that example workers import. The deploy.ts
template still inlines it (code generation constraint).

Reduces 3 copies to 2 (shared module + generated template).

* fix: array-accumulate Set-Cookie in config headers, fix JSDoc, add behavioral test

- deploy.ts template: config headers section was comma-joining Set-Cookie values
  using += which corrupts cookies with Expires dates and loses all but the last
  cookie when multiple config rules match. Matches the array-accumulation pattern
  already used in prod-server.ts (lines 899-907) and the middleware section above.
- worker-utils.ts + deploy.ts template JSDoc: 'Response headers take precedence'
  was misleading — Set-Cookie is additive, not overriding. Clarify both docs.
- tests/deploy.test.ts: add behavioral test for mergeHeaders via worker-utils import
  (same function inlined in the generated template), replacing reliance on
  string-contains assertions alone.

* fix: indentation in deploy.ts template, array-accumulate Set-Cookie in example workers

- deploy.ts: fix extra leading space in config headers block (lines 636-659)
  and JSDoc lines 740-743 introduced in previous commit
- pages-router-cloudflare, realworld-api-rest: config headers section was
  doing a plain assignment (middlewareHeaders[lk] = h.value) which overwrites
  array-valued Set-Cookie built up by the middleware section above; use the
  same array-accumulation pattern as prod-server.ts and the deploy.ts template

* fix: remove as any casts in prod-server.ts, add Vary handling to example workers

- prod-server.ts lines 904/906: middlewareHeaders is now Record<string, string | string[]>
  so the as any casts are unnecessary; replace with as string (consistent with the
  middleware collection section above at line 848)
- pages-router-cloudflare, realworld-api-rest: add Vary comma-joining to config
  headers section to match prod-server.ts (line 908) and deploy.ts template (line 653)

---------

Co-authored-by: James <james@eli.cx>
2026-03-06 23:53:23 +00:00