Skip to content

refactor: extract applyMiddlewareRequestHeaders into config-matchers#305

Merged
james-elicx merged 2 commits intomainfrom
refactor/extract-apply-middleware-request-headers
Mar 7, 2026
Merged

refactor: extract applyMiddlewareRequestHeaders into config-matchers#305
james-elicx merged 2 commits intomainfrom
refactor/extract-apply-middleware-request-headers

Conversation

@james-elicx
Copy link
Copy Markdown
Collaborator

Moves the duplicated x-middleware-request-* unpacking logic from prod-server.ts and deploy.ts into a shared applyMiddlewareRequestHeaders() in config-matchers.ts.

@james-elicx
Copy link
Copy Markdown
Collaborator Author

/bigbonk review

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 6, 2026

Open in StackBlitz

npm i https://pkg.pr.new/vinext@305

commit: 617797d

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 6, 2026

Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk 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

Clean refactoring — the extraction is well-motivated and the shared function correctly handles both the Node.js prod-server and Workers deploy paths.

Failing test

The test at tests/deploy.test.ts:550-557 fails because it asserts the old inline implementation exists in the generated worker entry string:

it("preserves x-middleware-request-* headers for prod request override handling", () => {
    const content = generatePagesRouterWorkerEntry();
    // Worker entry must unpack x-middleware-request-* into the actual request
    expect(content).toContain('const mwReqPrefix = "x-middleware-request-"');
    expect(content).toContain('key.startsWith(mwReqPrefix)');
    // Worker entry must also strip remaining x-middleware-* headers (defense-in-depth)
    expect(content).toContain('key.startsWith("x-middleware-")');
  });

The generated entry now calls applyMiddlewareRequestHeaders(middlewareHeaders, request) instead of inlining the logic, so all three assertions fail. This test needs updating — e.g., assert the import and the function call instead:

expect(content).toContain("applyMiddlewareRequestHeaders");
expect(content).toContain("applyMiddlewareRequestHeaders(middlewareHeaders, request)");

Subtle behavioral difference in prod-server (benign)

The old prod-server.ts code mutated webRequest.headers in-place:

webRequest.headers.set(realName, middlewareHeaders[key]);

The new shared function always clones via new Request(...) when there are headers to apply. This is slightly more work for the Node.js prod-server path (where headers are mutable anyway), but it's the correct approach — it makes the behavior uniform across runtimes and avoids assumptions about header mutability. The const → let change on webRequest is the necessary counterpart. No behavioral issue here.

Everything else looks good

  • The JSDoc is thorough and accurately describes mutation semantics and the return value
  • The requestContextFromRequest call is correctly placed after the potential request clone
  • Both call sites (deploy.ts and prod-server.ts) destructure and reassign identically
  • The generated worker entry correctly adds the import from vinext/config/config-matchers
  • The index.ts dev server (line ~2797) isn't deduplicated, which is fine — it operates on Node.js IncomingMessage, not Web Request, so it wouldn't cleanly use this shared function

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 6, 2026

The review has been posted. Here's the summary:

The PR is a clean refactoring that correctly extracts duplicated x-middleware-request-* header unpacking logic into a shared applyMiddlewareRequestHeaders() function in config-matchers.ts.

One issue found: The test at tests/deploy.test.ts:550-557 fails because it asserts the old inline code exists in the generated worker entry string (e.g., 'const mwReqPrefix = "x-middleware-request-"'), but that code has been replaced with a call to the shared function. The test needs to be updated to assert the import and function call instead.

There's also a benign behavioral difference — the old prod-server.ts mutated request headers in-place, while the new shared function always clones via new Request(...) when there are headers to apply. This is actually the more correct approach since it avoids assumptions about header mutability across runtimes.

github run

@james-elicx
Copy link
Copy Markdown
Collaborator Author

/bigbonk review

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk 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

Clean, well-scoped refactoring. All CI checks pass. Approving.

What it does

Extracts the duplicated x-middleware-request-* unpacking + x-middleware-* stripping logic from two inline call sites (deploy.ts and prod-server.ts) into a single applyMiddlewareRequestHeaders() in config-matchers.ts. Both call sites now destructure and reassign identically, and the test has been updated to assert the import + function call rather than the old inline implementation strings.

Notes

  • The const → let change on webRequest in prod-server.ts is correct — needed because the shared function returns a (possibly new) Request rather than mutating in-place.
  • The JSDoc accurately documents the mutation semantics on middlewareHeaders and the clone-on-write behavior for the Request.
  • The two remaining inline copies (index.ts:2797 operating on Node IncomingMessage and app-dev-server.ts:1470 using a different applyMiddlewareRequestHeaders that operates on the RSC entry's generated code) aren't consolidatable with this shared function since they operate on different object types. The previous review correctly noted this.
  • The updated test at tests/deploy.test.ts:550-557 now asserts "applyMiddlewareRequestHeaders" and "vinext/config/config-matchers" which validates the generated worker entry imports and calls the shared function. This is a better test — it verifies the integration contract rather than brittle implementation strings.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 6, 2026

Approved the PR. Here's the summary:

Clean refactoring, all 24 CI checks pass. The PR correctly extracts duplicated x-middleware-request-* header unpacking logic from deploy.ts and prod-server.ts into a shared applyMiddlewareRequestHeaders() function in config-matchers.ts.

Key observations:

  • The const → let change on webRequest in prod-server.ts is the necessary counterpart to the shared function returning a new Request instead of mutating in-place
  • The two remaining inline copies (index.ts operating on Node IncomingMessage, app-dev-server.ts in generated RSC entry code) can't use this shared function since they operate on different object types — correctly left alone
  • The test update is actually an improvement: asserting the import/call contract rather than brittle inline implementation strings

github run

@james-elicx james-elicx marked this pull request as draft March 6, 2026 22:57
@james-elicx
Copy link
Copy Markdown
Collaborator Author

Wait for 297 to merge, then rebase against and update func to handle those changes.

Move the x-middleware-request-* unpacking + postMwReqCtx rebuild logic
out of prod-server.ts and deploy.ts and into a shared
applyMiddlewareRequestHeaders() in config-matchers.ts, eliminating ~30
lines of duplicated code from each callsite.
@james-elicx james-elicx force-pushed the refactor/extract-apply-middleware-request-headers branch from 25df1a3 to f10a781 Compare March 7, 2026 11:02
@james-elicx james-elicx marked this pull request as ready for review March 7, 2026 11:05
@james-elicx
Copy link
Copy Markdown
Collaborator Author

/bigbonk review

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk 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

Clean, correct refactoring. All 24 CI checks pass (one E2E still pending but unrelated). Approving.

Summary

Extracts the duplicated x-middleware-request-* unpacking + x-middleware-* stripping logic from two inline sites (deploy.ts and prod-server.ts) into a shared applyMiddlewareRequestHeaders() in config-matchers.ts. Both call sites now destructure identically.

Observations

Correctness: The shared function faithfully reproduces the old inline logic. The two-pass approach (collect into toApply, then clone-if-needed) is equivalent to the old deploy.ts code and strictly better than the old prod-server.ts code, which mutated headers in-place — the uniform clone-on-write via new Request(...) avoids assumptions about header mutability across runtimes.

constlet in prod-server.ts:792: Correct and necessary since webRequest is now reassigned from the shared function's return value.

Test update (deploy.test.ts:582-589): The new assertions (applyMiddlewareRequestHeaders and vinext/config/config-matchers) verify the integration contract — that the generated worker entry imports and calls the shared function — rather than asserting on brittle inline implementation strings. This is an improvement.

Non-consolidated copies are correct to leave alone: The inline copies in index.ts (operates on Node IncomingMessage) and app-dev-server.ts (generated RSC entry code as a string template) operate on different object types and can't cleanly use this shared Web Request-based function.

Note from PR comments: Author mentions waiting for PR #297 to merge then rebasing. No issues with the code as-is — the rebase should be mechanical.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 7, 2026

The review has been posted. Here's the summary:

Approved. All CI checks pass. This is a clean, well-scoped refactoring that correctly extracts duplicated x-middleware-request-* header unpacking logic from deploy.ts and prod-server.ts into a shared applyMiddlewareRequestHeaders() in config-matchers.ts.

Key points:

  • The shared function faithfully reproduces the old inline logic, with the uniform clone-on-write behavior being strictly better than the old prod-server.ts in-place mutation
  • The constlet change on webRequest is the necessary counterpart
  • The test update now asserts the integration contract (import + function call) rather than brittle inline implementation strings
  • The two remaining inline copies (index.ts on IncomingMessage, app-dev-server.ts in generated RSC code) correctly can't use this shared function since they operate on different object types

Author notes a pending rebase against PR #297 — no issues with the code as-is.

github run

@james-elicx james-elicx enabled auto-merge (squash) March 7, 2026 11:07
@james-elicx james-elicx merged commit 09d9d4c into main Mar 7, 2026
23 checks passed
@james-elicx james-elicx deleted the refactor/extract-apply-middleware-request-headers branch March 7, 2026 11:11
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