br(v29): Global parsers and CORS splitting#3504
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
Co-authored-by: Anna Bocharova <robin_tail@me.com>
There was a problem hiding this comment.
Caution
Two changes require fixes before merge: attachRouting() no longer provides full CORS, and the migration rule for the old cors function can generate code with undefined references.
Reviewed changes — the PR makes body parsers global in createServer(), splits CORS into global and route-level layers, changes cors from HeadersProvider to RequestHandler, adds beforeParsers, and updates migration/docs/tests for v29.
- Body parsers move from per-endpoint
initRouting()to globalapp.use()calls increateServer(). corsconfig becomesboolean | RequestHandler, removingHeadersProvider.- CORS splits:
ensureCorsMiddleware()setsOrigin/Headersglobally before parsers; route-level handlers now only setAccess-Control-Allow-Methods. - Adds
beforeParsershook and repositionsbeforeRoutingto run after parsers. - Adds migration rule for old
corsfunctions and updates tests, examples, docs, and CHANGELOG.
🚨 attachRouting() no longer installs global CORS headers
createServer() runs setup(), which mounts ensureCorsMiddleware(config.cors) before parsers. attachRouting() calls initRouting() directly without that global layer. Since initRouting() now only sets Access-Control-Allow-Methods on method routes, attachRouting({ cors: true }, ...) users receive only Allow-Methods and no Access-Control-Allow-Origin or Access-Control-Allow-Headers.
Previously, initRouting() set all three CORS headers at the route level, so attachRouting() users got full CORS. The CHANGELOG mentions that attachRouting() users must install parsers manually, but it is silent on CORS. Either mount the global CORS middleware in attachRouting() or document the additional manual step.
Technical details
# attachRouting() no longer installs global CORS headers
## Affected sites
- `express-zod-api/src/server.ts:55-65` — `attachRouting()` calls `initRouting()` directly, skipping the global CORS layer in `setup()`.
- `express-zod-api/src/server.ts:85` — `ensureCorsMiddleware(config.cors)` is only mounted inside `setup()`.
- `express-zod-api/src/routing.ts:74-79` — route-level CORS now only sets `Access-Control-Allow-Methods`.
## Required outcome
- `attachRouting({ cors: true }, ...)` must continue to produce `Access-Control-Allow-Origin: *` and `Access-Control-Allow-Headers: content-type`, or the release notes must explicitly state that these headers are no longer provided automatically.
## Suggested approach
Mount `ensureCorsMiddleware(config.cors)` in `attachRouting()` before calling `initRouting()`, or move the global CORS mount into a shared helper used by both `setup()` and `attachRouting()`.
## Open questions for the human
- Is the intended behavior that `attachRouting()` users now install CORS themselves, matching the parser manual-install note?Note: 1 inline comment(s) dropped because they did not anchor to lines inside the PR diff:
express-zod-api/src/server-helpers.ts:126(RIGHT) — line 126 (RIGHT) is not inside a diff hunk
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
ℹ️ No new issues introduced by this commit; the prior
attachRouting()CORS concern is now resolved.
Reviewed changes — the latest commit restores full CORS handling for attachRouting() users and updates the corresponding test assertions.
attachRouting()now mountsensureCorsMiddleware()before callinginitRouting(), socors: trueusers continue to receiveAccess-Control-Allow-Origin: *andAccess-Control-Allow-Headers: content-type.server.spec.tsassertions updated to expect twoapp.use()calls (logging + CORS) forattachRouting().
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
ℹ️ No new issues introduced by this follow-up commit; the invalid
beforeParsersJSDoc example is now fixed.
Reviewed changes — the latest commit replaces the invalid app.use() example in the beforeParsers hook JSDoc with a concrete app.use(helmet()) example.
beforeParsersJSDoc example fixed from({ app }) => { app.use(); }to({ app }) => { app.use(helmet()); }, giving users a valid, concrete middleware usage pattern.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the latest commit restores full CORS handling for attachRouting() users by mounting the same global ensureCorsMiddleware() that createServer() uses.
attachRouting()now installsensureCorsMiddleware(config.cors)beforeinitRouting(), matchingsetup()behavior increateServer().routing.tskeeps the route-levelAccess-Control-Allow-Methodshandler, relying on the global middleware for origin/headers.server.spec.tsassertions reflect the additional CORSapp.use()call inattachRouting().- Also resolved the open README thread:
attachRouting()users should install extra middleware/parsers on their customapp, sincebeforeRouting/beforeParsersareServerConfighooks only. - Migration rule and tests for the
corsconfig change remain intact.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the two incremental commits address the remaining open documentation feedback from the prior review.
README.mdno longer pointsattachRouting()users towardbeforeRouting/beforeParsersconfig options; it now correctly says to install extra middleware/parsers on the customappdirectly.config-type.tsbeforeParsersJSDoc example now uses a concreteapp.use(helmet())instead of the invalid emptyapp.use().
Kimi K2 (free via Pullfrog for OSS) | 𝕏

QUERYmethod #3479corsdoes not work withupload.limitError#2706corsconfig option (breaking) to support RequestHandler, such as a middleware provided by the well-knowncorslibrarybeforeParsershook, whilebeforeRoutingremains exactly before callinginitRouting()